Weed: segment tree

Observed complexity, is asked to answer the following log level.

O (1)? Kx make me do?

Naturally think of tree line.

Seniors talking about the original title ah examination room also will not play.

Each node of the tree represents a segment operation interval.

Maintenance of the tree line there are three weights: This sub-interval total "net" increase the number of layers cnt, how much num, as well as how much it needs to get rid of the previous layer del.

Because for each sub-section, it is only possible to have several situations:

New accumulation of layers, or the sub-interval is not enough to delete the previous delete layers, or to delete the previous layers coupled with new layers.

Then each leaf node would not have said it, the key lies in two sections merge.

1, if you want to delete the left and right sections but also sections deleted it clean, then the amount of the entire interval to be deleted is del [r] + del [l] -cnt [l], the amount of the accumulated entire interval is accumulated the right section of

2, if deleted but did not delete clean, then we need to delete several values ​​are not deleted after the interval left the most reliable, delete the amount is to remove much of the left section, the remaining number of layers is cnt [l] + cnt [r] -del [r]

But how do you know that "several values ​​rearmost" mean?

Slight changes asked the question, the right to have the right value in the last few queries segment tree subtree range of value and location. Ask to make a function just fine.

However, there is a error-prone point: You can not query directly that several values ​​rearmost left subtree, right subtree may be deleted because a part of it.

So you want to query after the k p sub-tree, then, in fact, ask (p, k + del [bro]) - ask (p, del [bro])

bro refers to the right of fraternal p. If p itself is the right child does not exist. Such deleted it right sub-tree element was we took into account.

Then it's time to test the code in force.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define lc p<<1
 4 #define rc p<<1|1
 5 int opt[200005],k[200005],num[800005],cnt[800005],del[800005],n,m,cl[800005],cr[800005];
 6 int ask(int p,int t){
 7     if(!t)return 0;
 8     if(cnt[p]<=t)return num[p];
9      if (T <= cnt [re]) return ask (C, T);
10      return ask (LC, T-ent [re] + del [re]) - Ask (Ic del [re]) + num [re];
11  }
 12  void up ( int n) {
 13      if (del [re]> cut [c]) del [p] = del [c] + del [rc] -cnt [c], cnt [j] = cnt [ rc], or [p] = num [re];
14      else del [p] = del [c], cnt [j] = cnt [re] + ent [c] -del [re], or [p] = num [re] + num [c] - ask (Ic del [re]);
15  }
 16  void build ( int n, int i, int i) {
 17      Cl [j] = i; CR [p] = i;
18     if(l==r){
19         if(opt[l])del[p]=k[l];
20         else cnt[p]=1,num[p]=k[l];
21         return;
22     }
23     build(lc,l,l+r>>1);build(rc,(l+r>>1)+1,r);up(p);
24 }
25 void change(int p,int x){
26     if(cl[p]==cr[p]){
27         if(opt[x])del[p]=k[x],cnt[p]=num[p]=0;
28         else cnt[p]=1,num[p]=k[x],del[p]=0;
29         return;
30     }
31     if(cl[rc]<=x)change(rc,x);else change(lc,x);up(p);
32 }
33 int main(){
34     scanf("%d%d",&n,&m);
35     for(int i=1;i<=n;++i)scanf("%d%d",&opt[i],&k[i]);
36     build(1,1,n);
37     for(int i=1,x;i<=m;++i){
38         scanf("%d",&x);scanf("%d%d",&opt[x],&k[x]);
39         change(1,x);printf("%d\n",num[1]);
40     }
41 }
But it is the essence 1.1k

 

Guess you like

Origin www.cnblogs.com/hzoi-DeepinC/p/11332227.html