# 树套树小结

（写篇博客证明自己还活着）

bzoj3196 二逼平衡树

  1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<ctime>
5 #include<cmath>
6 using namespace std;
7 const int N=50000+10;
8 int val[N],n,m,a,b,c,o;
9 struct node
10 {
11     node* ch[2];
12     int rank,val,size,ge;
13     node (int x){val=x;rank=rand();size=ge=1;ch[1]=ch[0]=NULL;}
14     void tain()
15     {
16         size=1;
17         if(ch[0])size+=ch[0]->size;
18         if(ch[1])size+=ch[1]->size;
19     }
20 };
21 inline int s(node* o){return o?o->size:0;}
22 node* root[4*N];
23 void rotate(node* &o,int d)
24 {
25     node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
26     o->tain();k->tain();o=k;
27 }
28 void insert(node* &o,int val)
29 {
30     if(o==NULL){o=new node(val);return;}
31     if(val<o->val)
32     {
33         insert(o->ch[0],val);
34         if(o->ch[0]->rank > o->rank)
35             rotate(o,1);
36     }
37     else
38     {
39         insert(o->ch[1],val);
40         if(o->ch[1]->rank > o->rank)
41             rotate(o,0);
42     }
43     o->tain();
44 }
45 inline void build(int le,int ri,int num)
46 {
47     for(int i=le;i<=ri;i++)insert(root[num],val[i]);
48 }
49 void treeins(int le,int ri,int num)
50 {
51     build(le,ri,num);
52     if(le==ri)return;
53     int mi=(le+ri)>>1;
54     treeins(le,mi,num<<1);
55     treeins(mi+1,ri,(num<<1)|1);
56 }
57 void remove(node* &o,int val)
58 {
59     if(val==o->val)
60     {
61         if(o->ch[0]&&o->ch[1])
62         {
63             int d2=(o->ch[0]->rank > o->ch[1]->rank)?1:0;
64             rotate(o,d2);remove(o->ch[d2],val);
65         }
66         else
67         {
68             node* u=NULL;
69             if(o->ch[0]!=NULL)u=o->ch[0];
70             else u=o->ch[1];
71             delete o;
72             o=u;
73         }
74     }
75     else
76         if(val< o->val)remove(o->ch[0],val);
77         else remove(o->ch[1],val);
78     if(o)o->tain();
79 }
80 inline int find_rank(node* o,int val)
81 {
82     int ge=0;
83     while(o)
84     {
85         if(val> o->val)ge+=s(o->ch[0])+1,o=o->ch[1];
86         else o=o->ch[0];
87     }
88     return ge;
89 }
90 int tree_rank(int le,int ri,int num,int val)
91 {
92     if(a<=le&&ri<=b)return find_rank(root[num],val);
93     int mi=(le+ri)>>1;
94     int ret=0;
95     if(b<=mi)return tree_rank(le,mi,num<<1,val);
96     if(mi<a)return tree_rank(mi+1,ri,(num<<1)|1,val);
97     return tree_rank(le,mi,num<<1,val)+tree_rank(mi+1,ri,(num<<1)|1,val);
98 }
99 inline int divide_rank(int val)
100 {
101     int l=0,r=100000000;
102     while(l<=r)
103     {
104         int mi=(l+r)>>1;
105         int ans=tree_rank(1,n,1,mi)+1;
106         if(ans<=val)l=mi+1;
107         else r=mi-1;
108     }
109     return r;
110 }
111 inline int pre(int le,int ri,int val)
112 {
113     int tmp=tree_rank(1,n,1,val);
114     return divide_rank(tmp);
115 }
116 inline int re(int le,int ri,int val)
117 {
118     int tmp=tree_rank(1,n,1,val+1)+1;
119     return divide_rank(tmp);
120 }
121 void change(int le,int ri,int num,int pos,int pre,int now)
122 {
123     remove(root[num],pre);
124     insert(root[num],now);
125     if(le==ri)return;
126     int mi=(le+ri)>>1;
127     if(pos<=mi)change(le,mi,num<<1,pos,pre,now);
128     else change(mi+1,ri,(num<<1)|1,pos,pre,now);
129 }
130 int main()
131 {
132     scanf("%d%d",&n,&m);
133     for(int i=1;i<=n;i++)
134         scanf("%d",&val[i]);
135     treeins(1,n,1);
136     while(m--)
137     {
138         scanf("%d",&o);
139         switch(o)
140         {
141             case 1:
142                 scanf("%d%d%d",&a,&b,&c);
143                 printf("%d\n",tree_rank(1,n,1,c)+1);break;
144             case 2:
145                 scanf("%d%d%d",&a,&b,&c);
146                 printf("%d\n",divide_rank(c));break;
147             case 3:
148                 scanf("%d%d",&a,&b);
149                 change(1,n,1,a,val[a],b);val[a]=b;break;
150             case 4:
151                 scanf("%d%d%d",&a,&b,&c);
152                 printf("%d\n",pre(a,b,c));break;
153             case 5:
154                 scanf("%d%d%d",&a,&b,&c);
155                 printf("%d\n",re(a,b,c));break;
156         }
157     }
158     //while(1);
159 }
BZOJ3196

bzoj3262 陌上花开

 1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 const int N=100010,K=200010;
6 int n,k,tot,bit[K];
7 struct node
8 {
9     int a,b,c,val,id,ans;
10     node(){val=ans=0;}
11     inline void read(){scanf("%d%d%d",&a,&b,&c);}
12     inline void print()
13         {printf("a=%d b=%d c=%d val=%d id=%d\n",a,b,c,val,id);}
14 }q[N],tmp[N];
15 int cnt[N],st[N];
16 inline int lowbit(int a){return a&-a;}
17 inline void add(int a,int val)
18     {while(a<=k)bit[a]+=val,a+=lowbit(a);}
19 inline int query(int a)
20     {int ret=0;while(a)ret+=bit[a],a-=lowbit(a);return ret;}
21 inline bool mt1(const node &a,const node &b)
22 {
23     if(a.a==b.a&&a.b==b.b)return a.c<b.c;
24     return a.a==b.a?a.b<b.b:a.a<b.a;
25 }
26 inline bool mt2(const node &a,const node &b)
27 {
28     if(a.c==b.c&&a.b==b.b)return a.a<b.a;
29     return a.b==b.b?a.c<b.c:a.b<b.b;
30 }
31 inline bool same(const node &a,const node &b)
32     {return a.a==b.a&&a.b==b.b&&a.c==b.c;}
33 inline void CDQ(int l,int r)
34 {
35     if(l==r){q[l].ans+=q[l].val-1;return;}
36     register int i,mi=l+r>>1,l1=l,l2=mi+1;
37     for(i=l;i<=r;++i)
39         else q[i].ans+=query(q[i].c);
40     for(i=l;i<=r;++i)
42     for(i=l;i<=r;++i)
43         if(q[i].a<=mi)tmp[l1++]=q[i];
44         else tmp[l2++]=q[i];
45     for(i=l;i<=r;++i)q[i]=tmp[i];
46     CDQ(l,mi),CDQ(mi+1,r);
47 }
48 int main()
49 {
50     register int i,j,sum;
51     scanf("%d%d",&n,&k);sum=n;
53     sort(q+1,q+n+1,mt1);
54     for(n=1,i=2;i<=sum;++i)
55         if(same(q[i],q[n]))++q[n].val;
56         else q[++n]=q[i];
57     for(i=1;i<=n;++i)q[i].a=i;
58     sort(q+1,q+n+1,mt2);
59     CDQ(1,n);
60     for(i=1;i<=n;++i)cnt[q[i].ans]+=q[i].val;
61     for(i=0;i<sum;++i)printf("%d\n",cnt[i]);
62 }
CDQ打法

  1 #include <cstdio>
2 #include <cstdlib>
3 #include <iostream>
4 #include <algorithm>
5 #include <cstring>
6 using namespace std;
7 char B[1<<15],*S=B,*T=B;
8 #define getc ( (S==T&&( (T=(S=B)+fread(B,1,1<<15,stdin)),S==T) ) ?0:*S++ )
9 inline int read()
10 {
11     int x=0;register char c=getc;
12     while(c<'0'||c>'9')c=getc;
13     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
14     return x;
15 }
16 #define N 100010
17 #define K 200010
18 struct flower{
19     int a,b,c,ge;
21     inline bool operator == (const flower x) const
22         {return a==x.a&&b==x.b&&c==x.c;}
23 }f[N];
24 inline bool mt(const flower &a,const flower &b)
25 {
26     if(a.a!=b.a)return a.a<b.a;
27     return a.b==b.b?a.c<b.c:a.b<b.b;
28 }
29 int n,k,tota,totb,cnt[N];
30 struct Treap
31 {
32     Treap *ch[2];
33     int size,cnt,val,key;
34     inline void update(){size=cnt+ch[0]->size+ch[1]->size;}
35 }mema[N<<5],*null=new Treap();
36 inline Treap* newTreap(int val=0,int size=0,int key=rand())
37 {
38     Treap *o=mema+(tota++);o->ch[0]=o->ch[1]=null;
39     o->val=val,o->cnt=o->size=size,o->key=key;
40     return o;
41 }
42 inline Treap* merge(Treap *a,Treap *b)
43 {
44     if(a==null)return b;
45     if(b==null)return a;
46     if(a->key > b->key)
47         {a->ch[1]=merge(a->ch[1],b);a->update();return a;}
48     else
49         {b->ch[0]=merge(a,b->ch[0]);b->update();return b;}
50 }
51 #define D pair<Treap*,Treap*>
52 inline D split(Treap *o,int val)
53 {
54     if(o==null)return D(null,null);
55     D y;
56     if(o->val>val)
57         y=split(o->ch[0],val),o->ch[0]=y.second,o->update(),y.second=o;
58     else
59         y=split(o->ch[1],val),o->ch[1]=y.first,o->update(),y.first=o;
60     return y;
61 }
62 inline void insert(Treap *&o,flower p,int key)
63 {
64     if(o->key<key)
65     {
66         Treap *x=newTreap(p.c,p.ge,key);
67         D y=split(o,p.c);
68         x->ch[0]=y.first,x->ch[1]=y.second,x->update(),o=x;
69         return;
70     }
71     if(o->val>p.c)insert(o->ch[0],p,key);
72     else insert(o->ch[1],p,key);
73     o->update();
74 }
75 inline int grs(Treap *o,int val)
76 {
77     if(o==null)return 0;
78     return (o->val>val)?grs(o->ch[0],val):grs(o->ch[1],val)+o->ch[0]->size+o->cnt;
79 }
80 #define max(a,b) ((a)>(b)?(a):(b))
81 #define min(a,b) ((a)<(b)?(a):(b))
82 int maxb;
83 struct node
84 {
85     Treap *alter;node *ch[2];
86 }*root,memb[K<<1];
87 inline node* build(int l,int r)
88 {
89     node *o=memb+(totb++);o->alter=null;
90     if(l==r)return o;
91     int mi=l+r>>1;
92     o->ch[0]=build(l,mi);o->ch[1]=build(mi+1,r);
93     return o;
94 }
95 inline void insert(node *&o,int l,int r,flower p)
96 {
97     insert(o->alter,p,rand());
98     if(l==r)return;
99     int mi=l+r>>1;
100     if(p.b<=mi)insert(o->ch[0],l,mi,p);
101     else insert(o->ch[1],mi+1,r,p);
102 }
103 inline int query(node *o,int l,int r,int L,int R,int val)
104 {
105     if(L<=l&&r<=R)return grs(o->alter,val);
106     int mi=l+r>>1,ret=0;
107     if(L<=mi)ret=query(o->ch[0],l,mi,L,R,val);
108     if(mi<R)ret+=query(o->ch[1],mi+1,r,L,R,val);
109     return ret;
110 }
111 inline void intn()
112 {
113     null=mema+(tota++),null->size=null->cnt=null->val=0;
114     null->key=-1;null->ch[0]=null->ch[1]=null;
115     root=build(1,maxb);
116 }
117 int main()
118 {
119     register int i,sum;
121     for(i=1;i<=n;++i)f[i].init(),maxb=max(maxb,f[i].b);
122     sort(f+1,f+n+1,mt);intn();
123     for(sum=n,n=1,i=2;i<=sum;++i)
124         if(f[i]==f[n])++f[n].ge;
125         else f[++n]=f[i];
126     for(i=1;i<=n;++i)
127         insert(root,1,maxb,f[i]),
128         cnt[query(root,1,maxb,1,f[i].b,f[i].c)-1]+=f[i].ge;
129     for(i=0;i<sum;++i)printf("%d\n",cnt[i]);
130 }

bzoj3295 动态逆序对

 1 #include <cstring>
2 #include <cstdio>
3 #include <algorithm>
4 using namespace std;
5 typedef long long LL;
6 const int N=100010,M=50010;
7 struct node
8 {
9     int tim,val,pos;
10     node (int a=0,int b=0,int c=0){tim=a,val=b,pos=c;}
11 }q[N];
12 int cnt,n,m,a[N],match[N],step[M];
13 bool vis[N];
14 LL delta[2][N],num[2][N],bit[N];
15 inline int lowbit(int a){return a&-a;}
16 inline void add(int a,LL b)
17     {while(a<=n)bit[a]+=b,a+=lowbit(a);}
18 inline LL sum(int a)
19     {LL ret=0;while(a)ret+=bit[a],a-=lowbit(a);return ret;}
20 inline void gsum0()
21 {
22     for(register int i=1;i<=n;++i)
24     memset(bit,0,sizeof(bit));
25 }
26 inline void gsum1()
27 {
28     for(register int i=n;i;--i)
30     memset(bit,0,sizeof(bit));
31 }
32 inline void readin()
33 {
34     register int i;scanf("%d%d",&n,&m);
35     for(i=1;i<=n;++i)
36         scanf("%d",&a[i]),a[i]=n-a[i]+1,match[a[i]]=i;
37     gsum0();gsum1();
38     for(i=1;i<=m;++i)
39         scanf("%d",&step[i]),step[i]=n-step[i]+1,vis[step[i]]=1;
40 }
41 inline bool mt1(const node &a,const node &b){return a.pos<b.pos;}
42 inline bool mt2(const node &a,const node &b){return a.tim<b.tim;}
43 inline void CDQ0(int l,int r)
44 {
45     if(l==r)return;
46     register int mi=l+r>>1,i;
47     CDQ0(l,mi);CDQ0(mi+1,r);
48     sort(q+l,q+r+1,mt1);
49     for(i=l;i<=r;++i)
51         else delta[0][q[i].tim]+=sum(q[i].val);
52     for(i=l;i<=r;++i)
54 }
55 inline void CDQ1(int l,int r)
56 {
57     if(l==r)return;
58     register int mi=l+r>>1,i;
59     CDQ1(l,mi);CDQ1(mi+1,r);
60     sort(q+l,q+r+1,mt1);
61     for(i=r;i>=l;--i)
63         else delta[1][q[i].tim]+=sum(q[i].val);
64     for(i=r;i>=l;--i)
66 }
67 int main()
68 {
69     register int i;readin();
70     for(i=1;i<=m;++i)
71         q[++cnt]=node(cnt,step[i],match[step[i]]);
72     for(i=1;i<=n;++i)
73         if(!vis[a[i]])q[++cnt]=node(cnt,a[i],i);
74     CDQ0(1,n),sort(q+1,q+n+1,mt2),CDQ1(1,n);
75     LL ans=0;int pos;
76     for(i=1;i<=n;++i)ans+=num[0][i];
77     for(i=1;i<=m;++i)
78     {
79         printf("%lld\n",ans),pos=match[step[i]],
80         ans-=(num[0][pos]+num[1][pos]),
81         ans+=(delta[0][i]+delta[1][i]);
82     }
83 }
CDQ打法

  1 #include <cstdio>
2 #include <cstdlib>
3 #include <iostream>
4 #include <cstring>
5 using namespace std;
6 #define N 100010
7 int n,m,tota,totb;
8 int a[N],b[N],tmp[N];
9 #define LL long long
10 LL ans;
11 struct Treap
12 {
13     int val,size,key;Treap *ch[2];
14     Treap(){ch[0]=ch[1]=NULL;val=size=0;}
15     inline void update(){size=ch[0]->size+1+ch[1]->size;}
16 }mema[N<<5],*null=new Treap();
17 inline Treap* newTreap(int val=0,int key=rand())
18 {
19     Treap *o=mema+(tota++);
20     o->ch[0]=o->ch[1]=null;
21     o->key=key;o->val=val;
22     o->size=1;return o;
23 }
24 inline Treap* merge(Treap* a,Treap* b)
25 {
26     if(a==null)return b;
27     if(b==null)return a;
28     if(a->key > b->key) {a->ch[1]=merge(a->ch[1],b);a->update();return a;}
29     else {b->ch[0]=merge(a,b->ch[0]),b->update();return b;}
30 }
31 #define D pair<Treap*,Treap*>
32 inline D split1(Treap *o,int k)
33 {
34     if(o==null)return D(null,null);
35     D y;
36     if(o->ch[0]->size>=k)
37         y=split1(o->ch[0],k),o->ch[0]=y.second,o->update(),y.second=o;
38     else
39         y=split1(o->ch[1],k-o->ch[0]->size-1),o->ch[1]=y.first,o->update(),y.first=o;
40     return y;
41 }
42 inline D split2(Treap *o,int val)
43 {
44     if(o==null)return D(null,null);
45     D y;
46     if(o->val>=val)
47         y=split2(o->ch[0],val),o->ch[0]=y.second,o->update(),y.second=o;
48     else
49         y=split2(o->ch[1],val),o->ch[1]=y.first,o->update(),y.first=o;
50     return y;
51 }
52 inline void del(Treap *&o,int val)
53 {
54     if(o==null)return;
55     if(o->val>val)del(o->ch[0],val);
56     else if(o->val==val){o=merge(o->ch[0],o->ch[1]);return;}
57     else del(o->ch[1],val);
58     o->update();
59 }
60 inline void insert(Treap *&o,int val,int key)
61 {
62     if(o->key<key)
63     {
64         Treap *x=newTreap(val,key);
65         D y=split2(o,val);
66         x->ch[0]=y.first,x->ch[1]=y.second;
67         x->update(),o=x;
68         return;
69     }
70     else if(o->val>=val)insert(o->ch[0],val,key);
71     else insert(o->ch[1],val,key);
72     o->update();
73 }
74 inline int grb(Treap *o,int val)
75 {
76     if(o==null)return 0;
77     return (o->val<=val)?grb(o->ch[1],val):(grb(o->ch[0],val)+o->ch[1]->size+1);
78 }
79 inline int grs(Treap *o,int val)
80 {
81     if(o==null)return 0;
82     return (o->val>=val)?grs(o->ch[0],val):(grs(o->ch[1],val)+o->ch[0]->size+1);
83 }
84 struct node
85 {
86     Treap *summa;node *ch[2];
87     node(){ch[0]=ch[1]=NULL;}
88 }memb[N<<1],*root;
89 inline node* build(int l,int r)
90 {
91     node *o=memb+(totb++);o->summa=null;
92     if(l==r)return o;
93     int mi=l+r>>1;
94     o->ch[0]=build(l,mi),o->ch[1]=build(mi+1,r);
95     return o;
96 }
97 inline int queryl(node *o,int l,int r,int L,int R,int val)
98 {
99     if(L<=l&&r<=R)return grb(o->summa,val);
100     int mi=l+r>>1,ret=0;
101     if(L<=mi)ret=queryl(o->ch[0],l,mi,L,R,val);
102     if(mi<R)ret+=queryl(o->ch[1],mi+1,r,L,R,val);
103     return ret;
104 }
105 inline int queryr(node *o,int l,int r,int L,int R,int val)
106 {
107     if(L<=l&&r<=R)return grs(o->summa,val);
108     int mi=l+r>>1,ret=0;
109     if(L<=mi)ret=queryr(o->ch[0],l,mi,L,R,val);
110     if(mi<R)ret+=queryr(o->ch[1],mi+1,r,L,R,val);
111     return ret;
112 }
113 inline void insert(node *o,int l,int r,int pos,int val)
114 {
115     insert(o->summa,val,rand());
116     if(l==r)return;
117     int mi=l+r>>1;
118     if(pos<=mi)insert(o->ch[0],l,mi,pos,val);
119     else insert(o->ch[1],mi+1,r,pos,val);
120 }
121 inline void del(node *o,int l,int r,int pos,int val)
122 {
123     del(o->summa,val);
124     if(l==r)return;
125     int mi=l+r>>1;
126     if(pos<=mi)del(o->ch[0],l,mi,pos,val);
127     else del(o->ch[1],mi+1,r,pos,val);
128 }
129 inline void get_base(int l,int r)
130 {
131     if(l==r)return;
132     int mi=l+r>>1,p=l,q=mi+1,h=l;
133     get_base(l,mi),get_base(mi+1,r);
134     while(p<=mi&&q<=r)
135         if(a[p]<a[q])tmp[h++]=a[p++];
136         else ans+=(mi-p+1),tmp[h++]=a[q++];
137     while(p<=mi)tmp[h++]=a[p++];
138     while(q<=r)tmp[h++]=a[q++];
139     for(int i=l;i<=r;++i)a[i]=tmp[i];
140 }
141 char B[1<<15],*S=B,*T=B;
142 #define getc ( S==T&& (T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++ )
143 inline int read()
144 {
145     int x=0;register char c=getc;
146     while(c<'0'||c>'9')c=getc;
147     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
148     return x;
149 }
150 int main()
151 {
152     register int i,j;
153     null->ch[0]=null->ch[1]=null,null->key=-0x7fffffff;
156     memcpy(b,a,sizeof(a));
157     get_base(1,n);
158     for(i=1;i<=n;++i)tmp[b[i]]=i;
159     while(m--)
161         ans-=queryl(root,1,n,1,j,i)+queryr(root,1,n,j,n,i),
162         del(root,1,n,j,i);
163 }

bzoj2141 排队（和上面那题差不多，就不附代码了）

bzoj4009 接水果（模型转换之后整体二分or线段树套线段树）

  1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 #define inf 1000000000
6 #define N 40010
8 struct edge{int zhong,next;}s[N<<1];
9 inline void add(int qi,int zhong)
11 char B[1<<15],*S=B,*T=B;
12 #define getc ( S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++ )
13 inline int read()
14 {
15     int x=0;register char c=getc;
16     while(c<'0'||c>'9')c=getc;
17     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
18     return x;
19 }
20 int f[N][16],bin[25],tp,deep[N];
21 int st[N],ed[N],val[N],l[N],r[N],num;
22 inline void mission1(int rt)
23     {for(int i=1;i<=tp;++i)f[rt][i]=f[f[rt][i-1]][i-1];}
24 inline int LCA(int a,int b)
25 {
26     if(deep[a]<deep[b])a^=b,b^=a,a^=b;
27     register int i,cha=deep[a]-deep[b];
28     for(i=tp;~i;--i)if(cha&bin[i])a=f[a][i];
29     if(a==b)return a;
30     for(i=tp;~i;--i)
31         if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];
32     return f[a][0];
33 }
34 inline int gonear(int a,int b)
35 {
36     register int i,cha=deep[a]-deep[b]-1;
37     for(i=tp;~i;--i)if(cha&bin[i])a=f[a][i];
38     return a;
39 }
40 inline void dfs1(int rt,int fa)
41 {
42     f[rt][0]=fa,deep[rt]=deep[fa]+1;
43     l[rt]=++num,mission1(rt);
45         if(s[i].zhong!=fa)dfs1(s[i].zhong,rt);
46     r[rt]=num;
47 }
48 int ans[N],sum[N],bit[N];
49 #define lowbit(i) ((i)&(-(i)))
50 inline void update(int l,int r,int val)
51 {
52     for(int i=l;i<=n;i+=lowbit(i))bit[i]+=val;
53     for(int i=r+1;i<=n;i+=lowbit(i))bit[i]-=val;
54 }
55 inline int query(int i)
56 {
57     int ret=0;
58     for(;i>0;i-=lowbit(i))ret+=bit[i];
59     return ret;
60 }
61 struct plate{int x1,x2,y1,y2,val;}pl[N<<1];
62 struct fruit{int x,y,k,id;}fr[N],tmp1[N],tmp2[N];
63 struct node{int x,y1,y2,val,id;}eve[N*5];
64 inline bool mt(const plate &a,const plate &b){return a.val<b.val;}
65 inline bool mt2(const node &a,const node &b){return a.x==b.x?a.id<b.id:a.x<b.x;}
66 inline void get_ans(int le,int ri,int L,int R)
67 {
68     if(L>R)return;
69     if(le==ri)
70     {
71         for(int i=L;i<=R;++i)ans[fr[i].id]=pl[le].val;
72         return;
73     }
74     int a=0,b=0,mi=le+ri>>1;tot=0;
75     for(int i=le;i<=mi;++i)
76         eve[++tot]=(node){pl[i].x1,pl[i].y1,pl[i].y2,1,0},
77         eve[++tot]=(node){pl[i].x2,pl[i].y1,pl[i].y2,-1,q+1};
78     for(int i=L;i<=R;++i)
79         eve[++tot]=(node){fr[i].x,fr[i].y,0,0,i};
80     sort(eve+1,eve+tot+1,mt2);
81     for(int i=1;i<=tot;++i)
82         if(L<=eve[i].id&&eve[i].id<=R)sum[eve[i].id]=query(eve[i].y1);
83         else update(eve[i].y1,eve[i].y2,eve[i].val);
84     for(int i=L;i<=R;++i)
85         if(sum[i]>=fr[i].k)tmp1[++a]=fr[i];
86         else tmp2[++b]=fr[i],tmp2[b].k-=sum[i];
87     for(int i=1;i<=a;++i)fr[i+L-1]=tmp1[i];
88     for(int i=1;i<=b;++i)fr[i+L+a-1]=tmp2[i];
89     get_ans(le,mi,L,L+a-1),get_ans(mi+1,ri,L+a,R);
90 }
91 int main()
92 {
93     register int i,j,a,b,c,lca,x;
95     for(i=bin[0]=1;i<=20;++i)bin[i]=bin[i-1]<<1;
96     while(bin[tp+1]<=n)++tp;
98     dfs1(1,0);
99     for(i=1;i<=p;++i)
100     {
102         if(l[a]>l[b])a^=b,b^=a,a^=b;
103         if(a!=lca)
104             pl[++cnt]=(plate){l[a],r[a],l[b],r[b],c};
105         else
106         {
107             x=gonear(b,a);
108             if(l[x]>1)pl[++cnt]=(plate){1,l[x]-1,l[b],r[b],c};
109             if(r[x]<n)pl[++cnt]=(plate){l[b],r[b],r[x]+1,n,c};
110         }
111     }
112     for(i=1;i<=q;++i)
113     {
115         if(l[a]>l[b])a^=b,b^=a,a^=b;
116         fr[i]=(fruit){l[a],l[b],c,i};
117     }
118     sort(pl+1,pl+cnt+1,mt),get_ans(1,cnt,1,q);
119     for(i=1;i<=q;++i)printf("%d\n",ans[i]);
120 }

（没打树套树……懒了233）

bzoj1146 网络管理Network（树状数组套主席树上树）

  1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4 #define N 80010
5 #define inf 100000000
6 char B[1<<15],*S=B,*T=B;
7 #define GG puts("invalid request!")
8 #define getc ( S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T) ?0:*S++ )
9 inline int read()
10 {
11     int x=0;register char c=getc;
12     while(c<'0'||c>'9')c=getc;
13     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
14     return x;
15 }
17 struct edge{int zhong,next;}s[N<<1];
18 inline void add(int qi,int zhong)
20 #define lowbit(a) ((a)&(-(a)))
21 int num,l[N],r[N];
22 struct node
23 {
24     node *ch[2];int size;
25     node(){ch[0]=ch[1]=NULL;size=0;}
26 }*root[N<<1],mem[(N<<8)+10],*null,*stacka[1010],*stackb[1010];
27 inline void insert(node *&o,int l,int r,int pos,int val)
28 {
29     if(o==null)
30         o=mem+(tot++),o->size=0,o->ch[0]=o->ch[1]=null;
31     o->size+=val;if(l==r)return;
32     int mi=l+r>>1;
33     if(pos<=mi)insert(o->ch[0],l,mi,pos,val);
34     else insert(o->ch[1],mi+1,r,pos,val);
35 }
36 inline void insert(int id,int val,int opt)
37 {
38     while(id<=m)
39         insert(root[id],0,inf,val,opt),id+=lowbit(id);
40 }
41 int f[N][17],bin[25],tp,deep[N],cnta,cntb;
42 inline void mission1(int rt)
43     {for(int i=1;i<=tp;++i)f[rt][i]=f[ f[rt][i-1] ][i-1];}
44 inline void dfs1(int rt,int fa)
45 {
46     f[rt][0]=fa,deep[rt]=deep[fa]+1;mission1(rt);
47     l[rt]=++num,insert(l[rt],t[rt],1);
49         if(s[i].zhong!=fa)dfs1(s[i].zhong,rt);
50     r[rt]=++num,insert(r[rt]+1,t[rt],-1);
51 }
52 inline void intn()
53 {
54     null=new node(),null->size=0,null->ch[0]=null->ch[1]=null;
55     for(int i=0;i<=m;++i)root[i]=null;
56     dfs1(1,0);
57 }
58 inline int LCA(int a,int b)
59 {
60     if(deep[a]<deep[b])a^=b,b^=a,a^=b;
61     int cha=deep[a]-deep[b];
62     for(int i=tp;~i;--i)if(cha&bin[i])a=f[a][i];
63     if(a==b)return a;
64     for(int i=tp;~i;--i)
65         if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];
66     return f[a][0];
67 }
68 inline void get(int id,int opt)
69 {
70     while(id>0)
71     {
72         if(opt==1)stacka[++cnta]=root[id];
73         else stackb[++cntb]=root[id];
74         id-=lowbit(id);
75     }
76 }
77 inline int query(int le,int ri,int k)
78 {
79     if(le==ri)return le;
80     register int i,mi=le+ri>>1,sum=0;
81     for(i=1;i<=cnta;++i)sum+=stacka[i]->ch[1]->size;
82     for(i=1;i<=cntb;++i)sum-=stackb[i]->ch[1]->size;
83     if(sum>=k)
84     {
85         for(i=1;i<=cnta;++i)stacka[i]=stacka[i]->ch[1];
86         for(i=1;i<=cntb;++i)stackb[i]=stackb[i]->ch[1];
87         return query(mi+1,ri,k);
88     }
89     else
90     {
91         for(i=1;i<=cnta;++i)stacka[i]=stacka[i]->ch[0];
92         for(i=1;i<=cntb;++i)stackb[i]=stackb[i]->ch[0];
93         return query(le,mi,k-sum);
94     }
95 }
96 inline void get_ans(int le,int ri,int k)
97 {
98     int lca=LCA(le,ri);
99     if(k> deep[le]+deep[ri]- (deep[lca]<<1) +1 ){GG;return;}
100     cnta=cntb=0,
101     get(l[le],1),get(l[lca],-1),
102     get(l[ri],1),get(l[f[lca][0]],-1);
103     printf("%d\n",query(0,inf,k));
104 }
105 inline void change(int pos,int val)
106 {
107     insert(l[pos],t[pos],-1),insert(r[pos]+1,t[pos],1),t[pos]=val,
108     insert(l[pos],val,1),insert(r[pos]+1,val,-1);
109 }
110 int main()
111 {
112     register int i,j,q,a,b,opt;
114     for(bin[0]=i=1;i<=20;++i)bin[i]=bin[i-1]<<1;
115     while(bin[tp+1]<=n)++tp;
117     for(i=1;i<n;++i)
119     intn();
120     while(q--)
121     {
123         if(opt)get_ans(a,b,opt);
124         else change(a,b);
125     }
126 }
BZOJ1146

bzoj3065 带插入区间k小值 （替罪羊套权值线段树，操作的时候和树状数组套线段树差不多，提取出通过加减可以表达对应区间的根节点组，然后找到答案。）

  1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4 #define N 70010
5 #define MAXN 70000
6 int n,a[N];
7 char B[1<<15],*S=B,*T=B,X=0;
8 #define getc ( S==T && ( T=(S=B)+fread(B,1,1<<15,stdin), S==T) ? 0: *S++ )
9 inline int read()
10 {
11     int x=0;
12     while(X<'0'||X>'9')X=getc;
13     while(X>='0'&&X<='9')x=10*x+(X^48),X=getc;
14     return x;
15 }
16 inline char readc(){while(X<'A'||X>'Z')X=getc;return X;}
17 int topa,topb,top,cnta,cntb;
18 struct node
19 {
20     node* ch[2];int size;
21     node(){size=0,ch[0]=ch[1]=NULL;}
22 }*NIL=new node(),mem[(N<<8)+10],*pool[(N<<8)+10],*stacka[510],*stackb[510];
23 inline void dfs2(node *o)
24 {
25     if(o==NIL)return;
26     if(o->ch[0]!=NIL)dfs2(o->ch[0]);
27     if(o->ch[1]!=NIL)dfs2(o->ch[1]);
28     o->size=0,o->ch[0]=o->ch[1]=NIL,pool[++topa]=o;
29 }
30 inline void insert(node *&o,int l,int r,int pos)
31 {
32     if(o==NIL)o=pool[topa--],o->size=0,o->ch[0]=o->ch[1]=NIL;
33     ++o->size;
34     if(l<r)
35     {
36         int mi=l+r>>1;
37         if(pos<=mi)insert(o->ch[0],l,mi,pos);
38         else insert(o->ch[1],mi+1,r,pos);
39     }
40 }
41 inline void del(node *&o,int l,int r,int pos)
42 {
43     --o->size;
44     if(l<r)
45     {
46         int mi=l+r>>1;
47         if(pos<=mi)del(o->ch[0],l,mi,pos);
48         else del(o->ch[1],mi+1,r,pos);
49     }
50     if(o->size==0)
51         pool[++topa]=o,o=NIL;
52 }
53 inline int get_ans(int l,int r,int k)
54 {
55     if(l==r)return l;
56     register int i,sum=0,mi=l+r>>1;
57     for(i=1;i<=cnta;++i)
58         sum+=stacka[i]->ch[0]->size;
59     for(i=1;i<=cntb;++i)
60         sum-=stackb[i]->ch[0]->size;
61     if(sum>=k)
62     {
63         for(i=1;i<=cnta;++i)stacka[i]=stacka[i]->ch[0];
64         for(i=1;i<=cntb;++i)stackb[i]=stackb[i]->ch[0];
65         return get_ans(l,mi,k);
66     }
67     else
68     {
69         for(i=1;i<=cnta;++i)stacka[i]=stacka[i]->ch[1];
70         for(i=1;i<=cntb;++i)stackb[i]=stackb[i]->ch[1];
71         return get_ans(mi+1,r,k-sum);
72     }
73 }
74 #define alpha 0.755
75 struct Goat
76 {
77     Goat *ch[2];node *tree;
78     int size,val;
79     inline bool bad()
80         {return ch[0]->size>=size*alpha+5 ||ch[1]->size>=size*alpha+5;}
81     inline void update()
82         {size=ch[0]->size+1+ch[1]->size;}
83 }*root,*null,memGoat[(N<<2)+10],*poolGoat[(N<<2)+10],*stackc[(N<<2)+10];
84 inline Goat** insert(Goat *&o,int pos,int val)
85 {
86     int to=(o->ch[0]->size+1 < pos)?1:0;
87     ++o->size,insert(o->tree,0,MAXN,val);
88     if(o->ch[to]==null)
89     {
90         o->ch[to]=poolGoat[topb--];
91         o->ch[to]->ch[0]=o->ch[to]->ch[1]=null;
92         o->ch[to]->val=val;
93         o->ch[to]->size=1;
94         o->ch[to]->tree=NIL;
95         insert(o->ch[to]->tree,0,MAXN,val);
96         return &null;
97     }
98     Goat **ret=insert(o->ch[to],pos-(o->ch[0]->size+1)*to,val);
100     return ret;
101 }
102 inline int change(Goat *o,int pos,int val)
103 {
104     insert(o->tree,0,MAXN,val);
105     if(o->ch[0]->size+1==pos)
106     {
107         int ret=o->val;
108         del(o->tree,0,MAXN,o->val),o->val=val;
109         return ret;
110     }
111     int ret;
112     if(o->ch[0]->size >= pos)ret=change(o->ch[0],pos,val);
113     else ret=change(o->ch[1],pos-o->ch[0]->size-1,val);
114     del(o->tree,0,MAXN,ret);return ret;
115 }
116 inline void get_l(Goat *o,int l)
117 {
118     if(o==null)return;
119     if(o->ch[0]->size>=l)
120     {
121         stacka[++cnta]=o->tree,stackb[++cntb]=o->ch[0]->tree,
122         get_l(o->ch[0],l);
123     }
124     else if(o->ch[0]->size+1==l)
125     {
126         stacka[++cnta]=o->tree,stackb[++cntb]=o->ch[0]->tree;
127     }
128     else
129         get_l(o->ch[1],l-o->ch[0]->size-1);
130 }
131 inline void get_r(Goat *o,int r)
132 {
133     if(o==null)return;
134     if(o->ch[0]->size>=r)
135         get_r(o->ch[0],r);
136     else if(o->ch[0]->size+1==r)
137     {
138         stacka[++cnta]=o->tree,stackb[++cntb]=o->ch[1]->tree;
139     }
140     else
141     {
142         stacka[++cnta]=o->tree,stackb[++cntb]=o->ch[1]->tree;
143         get_r(o->ch[1],r-o->ch[0]->size-1);
144     }
145 }
146 inline void dfs(Goat *o)
147 {
148     if(o==null)return;
149     if(o->ch[0]!=null)dfs(o->ch[0]);
150     stackc[++top]=o,dfs2(o->tree);
151     if(o->ch[1]!=null)dfs(o->ch[1]);
152 }
153 inline void onboard(Goat *o,node *&x)
154 {
155     if(o==null)return;
156     if(o->ch[0]!=null)onboard(o->ch[0],x);
157     insert(x,0,MAXN,o->val);
158     if(o->ch[1]!=null)onboard(o->ch[1],x);
159 }
160 inline Goat* build(int l,int r)
161 {
162     if(l>r)return null;
163     int mi=l+r>>1;
164     stackc[mi]->size=r-l+1;
165     stackc[mi]->ch[0]=build(l,mi-1),stackc[mi]->ch[1]=build(mi+1,r);
166     stackc[mi]->tree=pool[topa--];stackc[mi]->tree->size=0;
167     stackc[mi]->tree->ch[0]=stackc[mi]->tree->ch[1]=NIL;
168     onboard(stackc[mi]->ch[0],stackc[mi]->tree);
169     onboard(stackc[mi]->ch[1],stackc[mi]->tree);
170     insert(stackc[mi]->tree,0,MAXN,stackc[mi]->val);
171     return stackc[mi];
172 }
173 inline void rebuild(Goat *&o)
174 {
175     top=0;dfs(o);
176     o=build(1,top);
177 }
178 inline void intn()
179 {
180     NIL->ch[0]=NIL->ch[1]=NIL;NIL->size=0;
181     null=new Goat();null->tree=NIL;
182     null->size=null->val=0;
183     null->ch[0]=null->ch[1]=null;
184     topa=topb=0;
185     for(topa=0;topa<(N<<8);++topa)
186         pool[topa]=mem+topa,pool[topa]->size=0,
187         pool[topa]->ch[0]=pool[topa]->ch[1]=NIL;
188     for(topb=0;topb<(N<<2);++topb)
189         poolGoat[topb]=memGoat+topb,poolGoat[topb]->size=0,
190         poolGoat[topb]->ch[0]=poolGoat[topb]->ch[1]=null;
191     topa=(N<<8)-1,topb=(N<<2)-1;
192     for(int i=1;i<=n;++i)
193         stackc[i]=poolGoat[topb--],stackc[i]->val=a[i];
194     root=build(1,n);
195 }
196 int main()
197 {
198     register int i,j,q,ans=0,l,r,x;char opt;Goat **p7;
201     for(i=1;i<=q;++i)
202     {
204         switch(opt)
205         {
206             case 'Q':
208                 cnta=cntb=0,get_l(root,l),get_r(root,r);
209                 stackb[++cntb]=root->tree;
210                 printf("%d\n",(ans=get_ans(0,MAXN,x)) );
211                 break;
212             case 'M':
214                 change(root,l,x);
215                 break;
216             case 'I':
218                 p7=insert(root,l,x);
219                 if(*p7!=null)rebuild(*p7);
220                 break;
221         }
222     }
223 }
BZOJ3065

bzoj3217 ALOEXT（替罪羊套Trie树，和上面类似）

（还没打……明天补坑）

*PS:替罪羊树的思想是很好的，这种重建的思想可以优化很多题目的复杂度。

bzoj4553 序列

 1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
4 #include <algorithm>
5 using namespace std;
6 const int N=300000;
7 int n,m,bit[N+100],f[N+100];
8 struct num{int val,maxv,minv;}x[N+100];
9 struct cdq{int x,y,id;}a[N+100];
10 inline int lowbit(int a){return a&(-a);}
11 inline bool mt(const cdq &a,const cdq &b)
12 {return (a.x==b.x)?a.id<b.id:a.x<b.x;}
13 inline void add(int i,int val)
14 {
15     while(i<=N)
16     {
17         bit[i]=(val==0)?0:max(bit[i],val);
18         i+=lowbit(i);
19     }
20 }
21 inline int sum(int i)
22 {
23     int ret=0;
24     while(i)
25         ret=max(ret,bit[i]),i-=lowbit(i);
26     return ret;
27 }
28 void cdq(int l,int r)
29 {
30     if(l==r){f[l]=max(f[l],1);return;}
31     int mi=(l+r)>>1;
32     cdq(l,mi);
33     for(int i=l;i<=r;i++)
34     {
35         if(i<=mi)a[i].x=x[i].val,a[i].y=x[i].maxv;
36         else a[i].x=x[i].minv,a[i].y=x[i].val;
37         a[i].id=i;
38     }
39     sort(a+l,a+r+1,mt);
40     for(int i=l;i<=r;i++)
41     {
43         else f[a[i].id]=max(sum(a[i].y)+1,f[a[i].id]);
44     }
46     cdq(mi+1,r);
47 }
48 int main()
49 {
50     scanf("%d%d",&n,&m);int u,v,ans=0;
51     for(int i=1;i<=n;i++)
52         scanf("%d",&x[i].val),x[i].minv=x[i].maxv=x[i].val;
53     while(m--)
54     {
55         scanf("%d%d",&u,&v);
56         x[u].maxv=max(x[u].maxv,v);
57         x[u].minv=min(x[u].minv,v);
58     }
59     cdq(1,n);
60     for(int i=1;i<=n;i++)ans=max(ans,f[i]);
61     printf("%d\n",ans);
62 }
CDQ打法

bzoj2244 拦截导弹

  1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #include <iostream>
5 using namespace std;
6 const int N=50010;
7 int n,toth,totv,st[N],top,f[2][N];
8 struct node
9 {
10     int h,v,tim;
11     inline void read(){scanf("%d%d",&h,&v);}
12 }m[N];
13 inline bool mt1(const node &a,const node &b)
14 {
15     if(a.v==b.v&&a.h==b.h)return a.tim<b.tim;
16     return a.h==b.h?a.v<b.v:a.h<b.h;
17 }
18 inline bool mt2(const node &a,const node &b)
19     {return a.tim<b.tim;}
20 int bit[N];
21 double cnt[N],g[2][N],ans[N];
22 inline int lowbit(int a){return a&-a;}
23 inline void add(int a,int b,double c)
24 {
25     while(a<=totv)
26     {
27         if(bit[a]<b)bit[a]=b,cnt[a]=c;
28         else if(bit[a]==b)cnt[a]+=c;
29         a+=lowbit(a);
30     }
31 }
32 inline void query(int a,int &b,double &c)
33 {
34     b=0,c=0.0;
35     while(a)
36     {
37         if(bit[a]>b)b=bit[a],c=cnt[a];
38         else if(bit[a]==b)c+=cnt[a];
39         a-=lowbit(a);
40     }
41 }
42 inline void clear(int a)
43 {
44     while(a<=totv)
45     {
46         if(!bit[a])return;
47         bit[a]=0,cnt[a]=0.0,a+=lowbit(a);
48     }
49 }
50 inline void CDQ(int l,int r,int o)
51 {
52     if(l==r)return;
53     register int i,mi=l+r>>1;
54     CDQ(l,mi,o);
55     sort(m+l,m+r+1,mt1);
56     int x=0;double u=0.0;
57     for(i=l;i<=r;++i)
58     {
59         if(m[i].tim<=mi)
61         else
62         {
63             query(m[i].v,x,u);
64             if(x+1>f[o][m[i].tim])
65                 f[o][m[i].tim]=x+1,g[o][m[i].tim]=u;
66             else if(x+1==f[o][m[i].tim])
67                 g[o][m[i].tim]+=u;
68         }
69     }
70     for(i=l;i<=r;++i)
71         if(m[i].tim<=mi)clear(m[i].v);
72     sort(m+l,m+r+1,mt2);
73     CDQ(mi+1,r,o);
74 }
75 inline void intn()
76 {
77     register int i;
78     for(i=1;i<=n;++i)st[i]=m[i].h;
79     sort(st+1,st+n+1),toth=unique(st+1,st+n+1)-st-1;
80     for(i=1;i<=n;++i)
81         m[i].h=lower_bound(st+1,st+toth+1,m[i].h)-st;
82     for(i=1;i<=n;++i)st[i]=m[i].v;
83     sort(st+1,st+n+1),totv=unique(st+1,st+n+1)-st-1;
84     for(i=1;i<=n;++i)
85         m[i].v=lower_bound(st+1,st+totv+1,m[i].v)-st;
86 }
87 int main()
88 {
89     register int i,j;scanf("%d",&n);
91     intn();
92     for(i=1;i<=n;++i)
93         m[i].tim=i,f[0][i]=f[1][i]=g[0][i]=g[1][i]=1;
94     CDQ(1,n,0);
95     reverse(m+1,m+n+1);
96     for(i=1;i<=n;++i)
97         m[i].tim=i,m[i].h=toth-m[i].h+1,m[i].v=totv-m[i].v+1;
98     CDQ(1,n,1);
99     int maxn=0;double sum=0;
100     for(i=1;i<=n;++i)
101     {
102         if(maxn<f[0][i])maxn=f[0][i],sum=g[0][i];
103         else if(f[0][i]==maxn)sum+=g[0][i];
104     }
105     printf("%d\n",maxn);
106     for(i=1;i<=n;++i)
107     {
108         if(f[0][n-i+1]+f[1][i]-1==maxn)
109             ans[i]=g[0][n-i+1]*g[1][i]/sum;
110         else ans[i]=0.0;
111     }
112     for(i=1;i<n;++i)printf("%.5lf ",ans[i]);
113     printf("%.5lf",ans[n]);
114 }
BZOJ2244

（我这两道都是拿CDQ打的2333）

posted @ 2017-12-08 18:03 LadyLex 阅读(...) 评论(...) 编辑 收藏