数据结构
分类:
IT文章
•
2024-07-08 10:46:13
线段树
luoguP4065 [JXOI2017]颜色
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define N 300005
5 int n,tp,c[N],mn[N],mx[N],s[N<<2],tg[N<<2];ll res;
6 void down(int x,int l,int r){if(tg[x]){int mid=l+r>>1;s[x<<1]=mid-l+1;s[x<<1|1]=r-mid;tg[x<<1]=tg[x<<1|1]=1;tg[x]=0;}}
7 void build(int x,int l,int r)
8 {
9 s[x]=tg[x]=0;
10 if(l==r)return;
11 int mid=l+r>>1;build(x<<1,l,mid);build(x<<1|1,mid+1,r);
12 }
13 void upd(int x,int l,int r,int tl,int tr)
14 {
15 if(tl>tr)return;
16 if(tl<=l&&r<=tr){s[x]=r-l+1;tg[x]=1;return;}
17 int mid=l+r>>1;down(x,l,r);
18 if(tl<=mid)upd(x<<1,l,mid,tl,tr);
19 if(tr>mid)upd(x<<1|1,mid+1,r,tl,tr);
20 s[x]=s[x<<1]+s[x<<1|1];
21 }
22 int qry(int x,int l,int r,int tl,int tr)
23 {
24 if(tl>tr)return 0;
25 if(tl<=l&&r<=tr)return s[x];
26 int mid=l+r>>1,rr=0;down(x,l,r);
27 if(tl<=mid)rr+=qry(x<<1,l,mid,tl,tr);
28 if(tr>mid)rr+=qry(x<<1|1,mid+1,r,tl,tr);
29 return rr;
30 }
31 struct st{int c,p;}stk[N];
32 void sol()
33 {
34 scanf("%d",&n);res=0;tp=0;
35 for(int i=1;i<=n;i++)scanf("%d",&c[i]);
36 build(1,1,n);
37 for(int i=1;i<=n;i++)mn[i]=n+1,mx[i]=0;
38 for(int i=1;i<=n;i++)mn[c[i]]=min(mn[c[i]],i),mx[c[i]]=max(mx[c[i]],i);
39 for(int i=1;i<=n;i++)
40 {
41 if(i==mx[c[i]])upd(1,1,n,mn[c[i]]+1,mx[c[i]]);//mx[c[i]]>mn[c[i]]
42 else stk[++tp]=(st){c[i],i};
43 while(tp&&mx[stk[tp].c]<=i)tp--;
44 int l=!tp?0:stk[tp].p;
45 if(i>l)res+=i-l-qry(1,1,n,l+1,i);
46 }
47 printf("%lld
",res);
48 }
49 int main()
50 {
51 int T;scanf("%d",&T);
52 while(T--)sol();
53 return 0;
54 }
View Code
线段树合并
luoguP4556 [Vani有约会]雨天的尾巴
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=1e5+10;
4 int n,m,cc,fa[N][22],dep[N],ans[N],ls[40*N],rs[40*N],rt[N];
5 struct st{int x,y;}T[40*N];
6 st operator+(st a,st b){return a.x==b.x?(st){a.x,min(a.y,b.y)}:(a.x<b.x?b:a);}
7 vector<st>gg[N];
8 vector<int>g[N];
9 void upd(int &x,int l,int r,int p,int v)
10 {
11 if(!x)x=++cc;
12 if(l==r){T[x].x+=v;T[x].y=l;return;}
13 int mid=l+r>>1;
14 if(p<=mid)upd(ls[x],l,mid,p,v);else upd(rs[x],mid+1,r,p,v);
15 T[x]=T[ls[x]]+T[rs[x]];
16 }
17 int merge(int x,int y,int l,int r)
18 {
19 if(!x||!y)return x|y;
20 if(l==r){T[x].x+=T[y].x;return x;}
21 int mid=l+r>>1;
22 ls[x]=merge(ls[x],ls[y],l,mid);
23 rs[x]=merge(rs[x],rs[y],mid+1,r);
24 T[x]=T[ls[x]]+T[rs[x]];
25 return x;
26 }
27 void dfs1(int x,int p)
28 {
29 fa[x][0]=p;dep[x]=dep[p]+1;
30 for(int i=0;i<g[x].size();i++)if(g[x][i]!=p)dfs1(g[x][i],x);
31 }
32 int lca(int u,int v)
33 {
34 if(dep[u]<dep[v])swap(u,v);
35 int sub=dep[u]-dep[v];
36 for(int i=17;i>=0;i--)if(sub>>i&1)u=fa[u][i];
37 if(u==v)return u;
38 for(int i=17;i>=0;i--)if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
39 return fa[u][0];
40 }
41 void dfs2(int x,int p)
42 {
43 for(int i=0;i<g[x].size();i++)if(g[x][i]!=p)dfs2(g[x][i],x);
44 for(int i=0;i<g[x].size();i++)if(g[x][i]!=p)rt[x]=merge(rt[x],rt[g[x][i]],0,1e5);
45 for(int i=0;i<gg[x].size();i++)upd(rt[x],0,1e5,gg[x][i].x,gg[x][i].y);
46 ans[x]=T[rt[x]].y;
47 }
48 int main()
49 {
50 scanf("%d%d",&n,&m);cc=n;
51 for(int i=1;i<=n;i++)rt[i]=i;
52 for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),g[u].push_back(v),g[v].push_back(u);
53 dfs1(1,0);
54 for(int i=1;i<=17;i++)for(int j=1;j<=n;j++)fa[j][i]=fa[fa[j][i-1]][i-1];
55 for(int i=1,u,v,w;i<=m;i++)
56 {
57 scanf("%d%d%d",&u,&v,&w);int t=lca(u,v);
58 gg[u].push_back((st){w,1});gg[v].push_back((st){w,1});
59 gg[t].push_back((st){w,-1});gg[fa[t][0]].push_back((st){w,-1});
60 }
61 dfs2(1,0);
62 for(int i=1;i<=n;i++)printf("%d
",ans[i]);
63 return 0;
64 }
View Code
线段树分治
luoguP4585 [FJOI2015]火星商店问题
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define N 100005
5 struct trie
6 {
7 int nn,sz[N*20],ch[N*20][2];
8 void ins(int &x,int y,int p,int d)
9 {
10 sz[x=++nn]=sz[y]+1;
11 if(d==-1)return;
12 int t=p>>d&1;ch[x][t^1]=ch[y][t^1];
13 ins(ch[x][t],ch[y][t],p,d-1);
14 }
15 int qry(int x,int y,int p,int d)
16 {
17 if(d==-1)return 0;
18 int t=p>>d&1;
19 if(sz[ch[y][t^1]]-sz[ch[x][t^1]])return qry(ch[x][t^1],ch[y][t^1],p,d-1)|(1<<d);
20 else return qry(ch[x][t],ch[y][t],p,d-1);
21 }
22 }T;
23 struct k1{int l,r,x,tl,tr;}qq[N];
24 struct k2{int s,v,t;}q[N<<2],q1[N<<2],q2[N<<2];
25 bool cmp(k2 a,k2 b){return a.s<b.s;}
26 vector<int>g[N<<2];
27 void upd(int x,int l,int r,int tl,int tr,int v)
28 {
29 if(tl>tr)return;
30 if(tl<=l&&r<=tr){g[x].push_back(v);return;}
31 int mid=l+r>>1;
32 if(tl<=mid)upd(x<<1,l,mid,tl,tr,v);
33 if(tr>mid)upd(x<<1|1,mid+1,r,tl,tr,v);
34 }
35 int cc,tt,tp,rt[N],ans[N],st[N];
36 void calc(int x,int tl,int tr)
37 {
38 tp=T.nn=0;
39 for(int i=tl;i<=tr;i++)
40 {
41 st[++tp]=q[i].s;
42 T.ins(rt[tp],rt[tp-1],q[i].v,17);
43 }
44 for(int i=0;i<g[x].size();i++)
45 {
46 int p=g[x][i],l=upper_bound(st+1,st+tp+1,qq[p].l-1)-st-1,r=upper_bound(st+1,st+tp+1,qq[p].r)-st-1;
47 ans[p]=max(ans[p],T.qry(rt[r],rt[l],qq[p].x,17));
48 }
49 }
50 void sol(int x,int l,int r,int tl,int tr)
51 {
52 if(tl>tr)return;
53 calc(x,tl,tr);
54 if(l==r)return;
55 int mid=l+r>>1,t1=0,t2=0;
56 for(int i=tl;i<=tr;i++)if(q[i].t<=mid)q1[++t1]=q[i];else q2[++t2]=q[i];
57 for(int i=1;i<=t1;i++)q[tl+i-1]=q1[i];
58 for(int i=1;i<=t2;i++)q[tl+t1+i-1]=q2[i];
59 sol(x<<1,l,mid,tl,tl+t1-1);sol(x<<1|1,mid+1,r,tl+t1,tr);
60 }
61 int main()
62 {
63 int n,m;
64 scanf("%d%d",&n,&m);
65 for(int i=1,x;i<=n;i++)scanf("%d",&x),T.ins(rt[i],rt[i-1],x,17);
66 for(int i=1,a,b,c,d,o;i<=m;i++)
67 {
68 scanf("%d%d%d",&o,&a,&b);
69 if(!o)cc++,q[cc]=(k2){a,b,cc};
70 else{scanf("%d%d",&c,&d);qq[++tt]=(k1){a,b,c,max(1,cc-d+1),cc};ans[tt]=T.qry(rt[a-1],rt[b],c,17);}
71 }
72 for(int i=1;i<=tt;i++)upd(1,1,cc,qq[i].tl,qq[i].tr,i);
73 sort(q+1,q+cc+1,cmp);sol(1,1,cc,1,cc);
74 for(int i=1;i<=tt;i++)printf("%d
",ans[i]);
75 return 0;
76 }
View Code
树链剖分
动态dp
luoguP4719 【模板】动态dp
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define inf 1000000000
5 int n,m,id=0,w[N],dep[N],tp[N],fa[N],sz[N],sn[N],dfn[N],idfn[N],rr[N];
6 vector<int>g[N];
7 struct mat
8 {
9 int r,c,a[2][2];
10 inline mat(){memset(a,0,sizeof(a));}
11 mat operator*(const mat&b)const
12 {
13 mat c;c.r=r;c.c=b.c;
14 for(int i=0;i<r;i++)for(int j=0;j<c.c;j++)for(int k=0;k<b.r;k++)c.a[i][j]=max(c.a[i][j],a[i][k]+b.a[k][j]);
15 return c;
16 }
17 }d[N<<2],s[N];
18 mat qry(int x,int l,int r,int tl,int tr)
19 {
20 if(tl<=l&&r<=tr)return d[x];
21 int mid=l+r>>1;
22 if(tl<=mid&&mid<tr)return qry(x<<1|1,mid+1,r,tl,tr)*qry(x<<1,l,mid,tl,tr);
23 if(tl<=mid)return qry(x<<1,l,mid,tl,tr);
24 if(mid<tr)return qry(x<<1|1,mid+1,r,tl,tr);
25 }
26 void upd(int x,int l,int r,int p,mat v)
27 {
28 if(l==r){d[x]=v;return;}
29 int mid=l+r>>1;
30 if(p<=mid)upd(x<<1,l,mid,p,v);else upd(x<<1|1,mid+1,r,p,v);
31 d[x]=d[x<<1|1]*d[x<<1];
32 }
33 void dfs1(int x)
34 {
35 sz[x]=1;sn[x]=0;
36 for(int i=0;i<g[x].size();i++)if(g[x][i]!=fa[x])
37 {
38 dep[g[x][i]]=dep[x]+1;fa[g[x][i]]=x;
39 dfs1(g[x][i]);sz[x]+=sz[g[x][i]];
40 if(!sn[x]||sz[g[x][i]]>sz[sn[x]])sn[x]=g[x][i];
41 }
42 }
43 void dfs2(int x)
44 {
45 idfn[dfn[x]=++id]=x;
46 if(sn[x])tp[sn[x]]=tp[x],dfs2(sn[x]);
47 for(int i=0;i<g[x].size();i++)if(g[x][i]!=sn[x]&&g[x][i]!=fa[x]){tp[g[x][i]]=g[x][i];dfs2(g[x][i]);}
48 rr[x]=(sn[x]?rr[sn[x]]:x);
49 }
50 void calc(int x)
51 {
52 stack<int>st;
53 for(int i=x;i;i=sn[i])st.push(i);
54 while(!st.empty())
55 {
56 int t=st.top();st.pop();
57 int x=0,y=w[t];
58 for(int i=0;i<g[t].size();i++)if(g[t][i]!=fa[t]&&g[t][i]!=sn[t])
59 {
60 calc(g[t][i]);mat q=s[g[t][i]];
61 x+=max(q.a[0][0],q.a[0][1]);
62 y+=q.a[0][0];
63 }
64 mat m;m.r=m.c=2;
65 m.a[0][0]=m.a[1][0]=x;
66 m.a[0][1]=y;m.a[1][1]=-inf;
67 upd(1,1,n,dfn[t],m);
68 }
69 s[x]=qry(1,1,n,dfn[x],dfn[rr[x]]);
70 }
71 void chg(int x,int v)
72 {
73 mat p=qry(1,1,n,dfn[x],dfn[x]);
74 p.a[0][1]+=v-w[x];upd(1,1,n,dfn[x],p);w[x]=v;
75 for(int t=tp[x],f;t!=1;t=tp[f])
76 {
77 f=fa[t];
78 p=qry(1,1,n,dfn[f],dfn[f]);
79 mat q=qry(1,1,n,dfn[t],dfn[rr[t]]);
80 p.a[0][0]+=max(q.a[0][0],q.a[0][1])-max(s[t].a[0][0],s[t].a[0][1]);
81 p.a[0][1]+=q.a[0][0]-s[t].a[0][0];
82 p.a[1][0]=p.a[0][0];
83 upd(1,1,n,dfn[f],p);
84 s[t]=q;
85 }
86 }
87 int main()
88 {
89 scanf("%d%d",&n,&m);
90 for(int i=1;i<=n;i++)scanf("%d",&w[i]);
91 for(int i=1,u,v;i<n;i++){scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);}
92 dfs1(dep[1]=1);dfs2(tp[1]=1);calc(1);
93 while(m--)
94 {
95 int x,y;scanf("%d%d",&x,&y);chg(x,y);
96 mat p=qry(1,1,n,1,dfn[rr[1]]);
97 printf("%d
",max(p.a[0][0],p.a[0][1]));
98 }
99 return 0;
100 }
View Code
长链剖分
luoguP2993 [FJOI2014]最短路径树问题
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=30005;
4 struct T{int f,c;T(){f=0;c=1;}}dp[N],*f[N],*e=dp+1;
5 int K,cc,ans1,ans2,hd[N],nxt[N],to[N],vis[N],dist[N],dep[N],mx[N],fa[N],sn[N],w[N];
6 vector<pair<int,int> >g[N];
7 priority_queue<pair<int,int> >q;
8 inline void add(int u,int v){nxt[++cc]=hd[u];hd[u]=cc;to[cc]=v;vis[v]=0;fa[v]=u;}
9 void dfs1(int x)
10 {
11 for(int i=0;i<g[x].size();i++)
12 {
13 int y=g[x][i].first,z=g[x][i].second;
14 if(vis[y]&&dist[x]+z==dist[y])add(x,y),w[y]=z,dfs1(y);
15 }
16 }
17 void dfs2(int x)
18 {
19 mx[x]=dep[x]=dep[fa[x]]+1;
20 for(int i=hd[x];i;i=nxt[i])
21 {
22 int y=to[i];dfs2(y);
23 if(mx[y]>mx[x])mx[x]=mx[y],sn[x]=y;
24 }
25 }
26 void dfs(int x)
27 {
28 f[x][0].c=1;int v;
29 if(!sn[x])return;
30 f[sn[x]]=f[x]+1;dfs(sn[x]);
31 w[x]+=(v=w[sn[x]]);f[x][0].f-=v;
32 if(mx[x]-dep[x]>=K+1)
33 {
34 int len=f[x][K+1].f+v;
35 if(len>ans1)ans1=len,ans2=f[x][K+1].c;else if(len==ans1)ans2+=f[x][K+1].c;
36 }
37 for(int i=hd[x];i;i=nxt[i])
38 {
39 int y=to[i];if(y==sn[x])continue;
40 f[y]=e;int lim=mx[y]-dep[y]+1;e+=lim;
41 dfs(y);int u=w[y];
42 for(int j=max(K-mx[x]+dep[x],0);j<lim&&j<=K;j++)
43 {
44 int len=f[y][j].f+f[x][K-j].f+u+v;
45 if(len>ans1)ans1=len,ans2=f[y][j].c*f[x][K-j].c;else if(len==ans1)ans2+=f[y][j].c*f[x][K-j].c;
46 }
47 for(int j=0;j<lim;j++)
48 {
49 int len=f[y][j].f+u-v;
50 if(len>f[x][j+1].f)f[x][j+1].f=len,f[x][j+1].c=f[y][j].c;else if(len==f[x][j+1].f)f[x][j+1].c+=f[y][j].c;
51 }
52 }
53 }
54 int main()
55 {
56 int n,m;scanf("%d%d%d",&n,&m,&K);K-=2;
57 for(int i=1,u,v,w;i<=m;i++)scanf("%d%d%d",&u,&v,&w),g[u].push_back(make_pair(v,w)),g[v].push_back(make_pair(u,w));
58 for(int i=1;i<=n;i++)sort(g[i].begin(),g[i].end());
59 memset(dist,0x3f,sizeof(dist));dist[1]=0;q.push(make_pair(0,1));
60 while(!q.empty())
61 {
62 int x=q.top().second;q.pop();
63 if(vis[x])continue;vis[x]=1;
64 for(int i=0;i<g[x].size();i++)
65 {
66 int y=g[x][i].first,z=g[x][i].second;
67 if(dist[y]>dist[x]+z){dist[y]=dist[x]+z;q.push(make_pair(-dist[y],y));}
68 }
69 }
70 dfs1(1);dfs2(1);f[1]=e;e+=mx[1];dfs(1);
71 printf("%d %d
",ans1,ans2);
72 return 0;
73 }
View Code
树上dsu
cdq分治
树状数组
树套树
(1).线段树套权值线段树
luoguP3759 [TJOI2017]不勤劳的图书管理员
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define inf 0x3f3f3f3f
5 #define N 50010
6 #define mod 1000000007
7 int n,m,rt[N<<2],cc=0,cnt,sum,ans=0;
8 struct st{int id,v;}a[N];
9 //**struct book{int id,v;}a[N];
10 struct nd{int lc,rc,cnt,sum;}T[N<<8];
11 //**struct node{int cnt,lc,rc,sum;}tr[N*256];
12 queue<int>q;
13 void del(int &x){T[x].lc=T[x].rc=T[x].cnt=T[x].sum=0;q.push(x);x=0;}
14 int nwnd(){int x;if(!q.empty()){x=q.front();q.pop();return x;}else return ++cc;}
15 void add(int &x,int l,int r,int p,int f,int v)
16 {
17 if(!x)x=nwnd();
18 T[x].cnt+=f;T[x].sum=((T[x].sum+f*v)%+mod)%mod;
19 if(l==r)return;
20 int mid=l+r>>1;
21 if(p<=mid)add(T[x].lc,l,mid,p,f,v);else add(T[x].rc,mid+1,r,p,f,v);
22 if(!T[x].cnt)del(x);
23 }
24 void ask(int x,int l,int r,int tl,int tr)
25 {
26 if(!x)return;
27 if(tl<=l&&r<=tr){cnt+=T[x].cnt;(sum+=T[x].sum)%=mod;return;}
28 int mid=l+r>>1;
29 if(tl<=mid)ask(T[x].lc,l,mid,tl,tr);
30 if(tr>mid)ask(T[x].rc,mid+1,r,tl,tr);
31 }
32 void upd(int x,int l,int r,int p,int v)
33 {
34 if(p!=v)add(rt[x],1,n,a[p].id,-1,a[p].v);
35 add(rt[x],1,n,a[v].id,1,a[v].v);
36 if(l==r)return;
37 int mid=l+r>>1;
38 if(p<=mid)upd(x<<1,l,mid,p,v);else upd(x<<1|1,mid+1,r,p,v);
39 }
40 void qry(int x,int l,int r,int tl,int tr,int pl,int pr)
41 {
42 if(tl>tr)return;
43 if(tl<=l&&r<=tr){ask(rt[x],1,n,pl,pr);return;}
44 int mid=l+r>>1;
45 if(tl<=mid)qry(x<<1,l,mid,tl,tr,pl,pr);
46 if(tr>mid)qry(x<<1|1,mid+1,r,tl,tr,pl,pr);
47 }
48 int main()
49 {
50 scanf("%d%d",&n,&m);
51 for(int i=1;i<=n;i++)
52 {
53 scanf("%d%d",&a[i].id,&a[i].v);
54 upd(1,1,n,i,i);cnt=0;sum=0;ask(rt[1],1,n,a[i].id+1,n);
55 (ans+=(1ll*cnt*a[i].v%mod+sum)%mod)%=mod;
56 }
57 while(m--)
58 {
59 int x,y;scanf("%d%d",&x,&y);
60 if(x>y)swap(x,y);
61 if(x==y){printf("%d
",ans);continue;}
62 int tl=a[x].id,tr=a[y].id,mn=min(tl,tr),mx=max(tl,tr);
63 cnt=sum=0;qry(1,1,n,x,y,mn+1,mx-1);
64 (ans+=(mn==tl?1:-1)*(2*sum%mod+1ll*(cnt+1)*(a[x].v+a[y].v)%mod)%mod)%=mod;
65 cnt=0;qry(1,1,n,x,y,1,mn-1);(ans+=1ll*cnt*(a[y].v-a[x].v)%mod)%=mod;
66 cnt=0;qry(1,1,n,x,y,mx+1,n);(ans+=1ll*cnt*(a[x].v-a[y].v)%mod)%=mod;
67 upd(1,1,n,x,y);upd(1,1,n,y,x);ans=(ans+mod)%mod;
68 swap(a[x],a[y]);printf("%d
",ans);
69 }
70 return 0;
71 }
View Code
主席树
luoguP4592 [TJOI2018]异或
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define N 100010
5 int n,q,t,a[N],dfn[N],l[N],r[N],dep[N],fa[N][25];
6 vector<int>g[N];
7 struct Trie
8 {
9 int nn,rt[N],s[N*40],ch[N*40][2];
10 Trie(){rt[0]=nn=0;}
11 void ins(int &x,int y,int p)
12 {
13 int z=x=++nn;
14 for(int i=30;i>=0;i--)
15 {
16 int t=p>>i&1;
17 ch[z][t^1]=ch[y][t^1];
18 ch[z][t]=++nn;z=ch[z][t];y=ch[y][t];s[z]=s[y]+1;
19 }
20 }
21 int qry(int x,int y,int p)
22 {
23 int r=0;
24 for(int i=30;i>=0;i--)
25 {
26 int t=p>>i&1;
27 if(s[ch[y][t^1]]-s[ch[x][t^1]]){r|=(1<<i);x=ch[x][t^1];y=ch[y][t^1];}
28 else{x=ch[x][t];y=ch[y][t];}
29 }
30 return r;
31 }
32 }T1,T2;
33 void dfs(int x,int p)
34 {
35 l[x]=++t;dep[x]=dep[p]+1;dfn[t]=x;fa[x][0]=p;T2.ins(T2.rt[x],T2.rt[p],a[x]);
36 for(int i=0;i<g[x].size();i++)if(g[x][i]!=p)dfs(g[x][i],x);
37 r[x]=t;
38 }
39 int lca(int u,int v)
40 {
41 if(dep[u]<dep[v])swap(u,v);
42 int sub=dep[u]-dep[v];
43 for(int i=20;i>=0;i--)if(sub>>i&1)u=fa[u][i];
44 if(u==v)return u;
45 for(int i=20;i>=0;i--)if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
46 return fa[u][0];
47 }
48 int main()
49 {
50 scanf("%d%d",&n,&q);
51 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
52 for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),g[u].push_back(v),g[v].push_back(u);
53 dfs(1,0);
54 for(int i=1;i<=20;i++)for(int j=1;j<=n;j++)fa[j][i]=fa[fa[j][i-1]][i-1];
55 for(int i=1;i<=n;i++)T1.ins(T1.rt[i],T1.rt[i-1],a[dfn[i]]);
56 for(int i=1;i<=q;i++)
57 {
58 int o,x,y,z;scanf("%d%d%d",&o,&x,&y);
59 if(o==1)printf("%d
",T1.qry(T1.rt[l[x]-1],T1.rt[r[x]],y));
60 else{scanf("%d",&z);int t=lca(x,y);printf("%d
",max(T2.qry(T2.rt[fa[t][0]],T2.rt[x],z),T2.qry(T2.rt[fa[t][0]],T2.rt[y],z)));}
61 }
62 return 0;
63 }
View Code
luoguP4587 [FJOI2016]神秘数
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100010
4 int n,m,mx,tot,ls[N*40],rs[N*40],s[N*40],a[N],rt[N];
5 void upd(int y,int &x,int l,int r,int p)
6 {
7 if(!x)x=++tot;s[x]=s[y]+p;
8 if(l==r)return;
9 int mid=l+r>>1;
10 if(p<=mid)rs[x]=rs[y],upd(ls[y],ls[x],l,mid,p);else ls[x]=ls[y],upd(rs[y],rs[x],mid+1,r,p);
11 }
12 int qry(int x,int y,int l,int r,int p)
13 {
14 if(p>=r)return s[y]-s[x];
15 int mid=l+r>>1;
16 if(p>mid)return s[ls[y]]-s[ls[x]]+qry(rs[x],rs[y],mid+1,r,p);else return qry(ls[x],ls[y],l,mid,p);
17 }
18 int main()
19 {
20 scanf("%d",&n);
21 for(int i=1;i<=n;i++)scanf("%d",&a[i]),mx=max(mx,a[i]);
22 for(int i=1;i<=n;i++)upd(rt[i-1],rt[i],1,mx,a[i]);
23 scanf("%d",&m);
24 for(int i=1;i<=m;i++)
25 {
26 int l,r,ans=1;scanf("%d%d",&l,&r);
27 while(true)
28 {
29 int s=qry(rt[l-1],rt[r],1,mx,ans);
30 if(s<ans)break;
31 ans=s+1;
32 }
33 printf("%d
",ans);
34 }
35 return 0;
36 }
View Code
平衡树:
fhq treap
splay
luoguP3165 [CQOI2014]排序机械臂
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define inf 1000000007
4 #define N 100005
5 int n,rt,tp,stk[N],ch[N][2],fa[N],sz[N],rev[N];
6 struct T{int x,i;}v[N];
7 bool cmp(T a,T b){return (a.x^b.x)?a.x<b.x:a.i<b.i;}
8 int wh(int x){return ch[fa[x]][1]==x;}
9 void up(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;}
10 void down(int x)
11 {
12 if(rev[x])
13 {
14 if(ch[x][0])rev[ch[x][0]]^=1;
15 if(ch[x][1])rev[ch[x][1]]^=1;
16 swap(ch[x][0],ch[x][1]);rev[x]=0;
17 }
18 }
19 void rot(int x)
20 {
21 int y=fa[x],z=fa[y],c=wh(x);
22 ch[y][c]=ch[x][c^1];if(ch[y][c])fa[ch[y][c]]=y;
23 fa[x]=z;if(z)ch[z][wh(y)]=x;
24 ch[x][c^1]=y;fa[y]=x;up(y);
25 }
26 void splay(int x,int t)
27 {
28 for(int i=x;i!=t;i=fa[i])stk[++tp]=i;
29 stk[++tp]=t;
30 while(tp)down(stk[tp--]);
31 for(int y=fa[x];y!=t;rot(x),y=fa[x])if(fa[y]!=t)rot(wh(x)^wh(y)?x:y);
32 if(!t)rt=x;
33 up(x);
34 }
35 int fnd(int k)
36 {
37 int x=rt;
38 while(true)
39 {
40 down(x);
41 if(k==sz[ch[x][0]]+1)return x;
42 else if(k<=sz[ch[x][0]])x=ch[x][0];
43 else{k-=sz[ch[x][0]]+1;x=ch[x][1];}
44 }
45 }
46 void build(int l,int r,int p)
47 {
48 int mid=l+r>>1;fa[mid]=p;
49 if(!p)rt=mid;else if(mid<p)ch[p][0]=mid;else ch[p][1]=mid;
50 if(l==r){sz[mid]=1;return;}
51 if(l<mid)build(l,mid-1,mid);
52 if(mid<r)build(mid+1,r,mid);
53 up(mid);
54 }
55 int main()
56 {
57 scanf("%d",&n);
58 for(int i=2;i<=n+1;i++)scanf("%d",&v[i].x),v[i].i=i;
59 v[1]=(T){-inf,1};v[n+2]=(T){inf,n+2};
60 sort(v+1,v+n+3,cmp);
61 build(1,n+2,0);
62 for(int i=2;i<=n;i++)
63 {
64 splay(v[i].i,0);
65 int ans=sz[ch[rt][0]];
66 printf("%d ",ans);
67 int xx=fnd(i-1),yy=fnd(ans+2);
68 splay(xx,0);splay(yy,xx);
69 rev[ch[ch[rt][1]][0]]^=1;
70 }
71 printf("%d
",n);
72 return 0;
73 }
View Code
LCT
luoguP4332 [SHOI2014]三叉神经树
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=1500005;
4 int read()
5 {
6 int x=0;char c=getchar();
7 while(!isdigit(c))c=getchar();
8 while(isdigit(c))x=x*10+c-48,c=getchar();
9 return x;
10 }
11 int n,Q,ans,fa[N],ch[N][2],d[N],v[N],t1[N],t2[N],tg[N],st[N];
12 queue<int>q;
13 inline bool wh(const int&x){return ch[fa[x]][1]==x;}
14 inline bool isrt(const int&x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
15 inline void up(const int&x){t1[x]=t1[ch[x][1]]?t1[ch[x][1]]:(v[x]!=1?x:t1[ch[x][0]]);t2[x]=t2[ch[x][1]]?t2[ch[x][1]]:(v[x]!=2?x:t2[ch[x][0]]);}
16 inline void cov(const int&x){if(x){v[x]^=3;swap(t1[x],t2[x]);tg[x]^=1;}}
17 inline void down(const int&x){if(tg[x]){cov(ch[x][0]);cov(ch[x][1]);tg[x]=0;}}
18 inline void rot(const int&x)
19 {
20 int y=fa[x],z=fa[y],c=wh(x);
21 ch[y][c]=ch[x][c^1];if(ch[y][c])fa[ch[y][c]]=y;
22 fa[x]=z;if(!isrt(y))ch[z][wh(y)]=x;
23 ch[x][c^1]=y;fa[y]=x;up(y);
24 }
25 inline void splay(int x)
26 {
27 st[st[0]=1]=x;
28 for(int i=x;!isrt(i);i=fa[i])st[++st[0]]=fa[i];
29 while(st[0])down(st[st[0]--]);
30 for(int y=fa[x];!isrt(x);rot(x),y=fa[x])if(!isrt(y))wh(x)^wh(y)?rot(x):rot(y);
31 up(x);
32 }
33 inline void access(int x){for(int y=0;x;y=x,x=fa[x])splay(x),ch[x][1]=y,up(x);}
34 int main()
35 {
36 n=read();
37 for(int i=1,t1,t2,t3;i<=n;++i)t1=read(),t2=read(),t3=read(),d[fa[t1]=fa[t2]=fa[t3]=i]=3;
38 for(int i=n+1;i<=3*n+1;++i)v[i]=read(),v[i]<<=1,q.push(i);
39 while(!q.empty())
40 {
41 int x=q.front();q.pop();v[fa[x]]+=v[x]>>1;
42 if(!--d[fa[x]])q.push(fa[x]);
43 }
44 ans=v[1]>>1;Q=read();
45 while(Q--)
46 {
47 int x=read();v[x]^=2;int t=v[x]-1;
48 access(x=fa[x]);splay(x);
49 if(~t?t1[x]:t2[x])
50 {
51 x=~t?t1[x]:t2[x];splay(x);
52 cov(ch[x][1]);v[x]+=t;up(ch[x][1]);up(x);
53 }
54 else cov(x),ans^=1;
55 putchar('0'+ans);putchar('
');
56 }
57 return 0;
58 }
View Code
圆方树
虚树
点分树