hdu 預處理 線段樹)

2022-08-24 20:36:13 字數 2394 閱讀 4611

給n個數,m個詢問, 問任意區間內與其它數互質的數有多少個

比如3個數1 2 4,詢問[1,3] 那麼答案是1

千萬要記住,這樣的題目,如果你不轉變下,使勁往線段樹想(雖然轉變之後,也說要用到線段樹,但是維護的東西不同了),那麼會發現這樣的題目,區間與區間之間是無法傳遞資訊的,

區間與區間是無法傳遞資訊的,區間與區間之間是無法傳遞資訊的,重要的東西說三遍。

設n個數,存在陣列a裡面

我們預處理出,l,和r,l[i] 表示從i往左,第乙個與a[i]不互質的數的位置+1,  r[i]表示從i往右,第乙個與a[i]不互質的數的位置-1

即l[i] 表示 [l[i],i]內的所有數都與a[i]互質,r[i]表示[i,r[i]]內的所有數都與a[i]互質 

然後我們離線處理,將所有的詢問按照左端點排序

然後列舉左端點i,將所有l[j] = i的 [j,r[j]]區間+1,因為當左端點為i時,l[j]=i的數都在各自的有效區間[j,r[j]]裡面生效了

當i=詢問的區間的左端點時,只要查詢右端點被加了多少次就行了。

走過i時,第i個數不再生效,所以將[i,r[i]]區間-1

1 #include2 #include3 #include

4 #include5 #include 6

using

namespace

std;

7const

int n = 200000 + 10

;8 vectorprime[n];

9 vectorcl[n];

10int

a[n],l[n],r[n];

11int

mark[n];

12int tree[n<<2],lazy[n<<2

];13

intans[n];

14void pushdown(int

rt)1524}

25void update(int l, int r, int rt, int l, int r, int

val)

2633

pushdown(rt);

34int mid = (l+r)>>1;35

if(l<=mid)

36 update(l,mid,rt<<1

,l,r,val);

37if(r>mid)

38 update(mid+1,r,rt<<1|1

,l,r,val);

3940}41

int query(int l, int r, int rt, int

pos)

4247

pushdown(rt);

48int mid = (l+r)>>1;49

if(pos<=mid)

50return query(l,mid,rt<<1

,pos);

51else

52return query(mid+1,r,rt<<1|1

,pos);53}

54struct

node

5561

}q[n];

6263

void

getprime()

6473}74

}75void init(int

n)76

90 l[i] = pos + 1;91

cl[l[i]].push_back(i);92}

93for(int i=2;i1;94

for(int i=0;ii)

95 mark[prime[a[n]][i]] =n;

96 r[n] =n;

97for(int i=n-1;i>=1;--i)

98105 r[i] = pos - 1

;106

}107

}108

intmain()

109121

init(n);

122for(int i=0;ii)

123127 sort(q,q+m);

128int cur = 0

;129

//列舉左端點

130for(int i=1;i<=n;++i)

131143

//要走過第i個數了,所以第i個數不再生效了,所以將[i,r[i]]區間-1

144 update(1,n,1,i,r[i],-1

);145

}146

for(int i=0;ii)

147 printf("

%d\n

",ans[i]);

148}

149return0;

150 }

hdu 4288 線段樹 離線處理

hdu 4288 題意 給你類似乙個公升序的set結構 add就是加入乙個數 del就是刪除乙個數 sum就是把所有 5 3的位置的數求和 這題我們怎麼入手呢?以前做過一道類似的樹狀陣列開55個的題 這個題其實大同小異 就是對sum陣列表示 5的值我們開個sum 5 那麼你既然是公升序的 我每次ad...

HDU 3333 線段樹 離線處理

hdu 3333 線段樹 離線處理 問你給定區間內的不重複的數字的和,如1 1 1 3 4 區間1到2就是1,區間1到5就是8。這種線段樹只能離線來寫,離線的方法是按照查詢區間的右端點來排序,然後這道題目的資料範圍較大需要離散化簡單處理一下,然後對於輸入的每個點來說,順序走下去。然後如果當前點之前出...

線段樹處理 poj2892 hdu1540

這道題想了很久 沒有想出來思路 後面上網找了題解 利用區間左端點連續 和右端點連續 處理了區間的連續 sum陣列儲存連續村莊個數,lsum儲存區間內從左起連續個數,rsum儲存區間內從右起連續個數 include include include include using namespace std...