【主席树+树链剖分】BZOJ 4448 情报传递

主席树+树链剖分

对于每个时间点建一棵线段树

k=1时,找lca和查询在i-c-1时刻树上路径已被染色点数,此时新线段树等于前一时刻线段树

k=2时,直接插入更新新线段树即可

 1 #include <bits/stdc++.h>
 2 #define For(i,a,b) for(int i=a;i<=b;++i)
 3 #define Dec(i,b,a) for(int i=b;i>=a;--i)
 4 #define file() freopen("c://users/asus/desktop/v.txt","r",stdin)
 5 #define inf 0x3f3f3f3f
 6 using namespace std;
 7 
 8 typedef unsigned long long ll;
 9 inline ll qr(){
10     ll x=0,f=1; char ch=getchar();
11     while(!isdigit(ch)){if(ch=='-')f=-1; ch=getchar();}
12     while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48); ch=getchar();}
13     return x*f;
14 }
15 #define mid (l+r>>1)
16 const int N = 200010;
17 int sz[N],f[N][20],d[N],id[N],top[N],idx,son[N];
18 int s[N*30],rt[N],ct,lc[N*30],rc[N*30];
19 vector<int> g[N];
20 int n,m,root;
21 void dfs1(int u)
22 {
23     sz[u]=1; 
24     for(int i=1;f[u][i-1];++i) f[u][i]=f[f[u][i-1]][i-1];
25     for(int i=0,v;i<g[u].size();++i)
26     {
27         if((v=g[u][i])==f[i][0]) continue;
28         f[v][0]=u; d[v]=d[u]+1; dfs1(v); sz[u]+=sz[v];
29         if(sz[v]>sz[son[u]]) son[u]=v;
30     }
31 }
32 void dfs2(int u,int tp)
33 {
34     id[u]=++idx; top[u]=tp;
35     if(!son[u]) return;
36     dfs2(son[u],tp);
37     for(int i=0,v;i<g[u].size();++i)
38         if((v=g[u][i])!=f[u][0] && v!=son[u]) dfs2(v,v);
39 }
40 int lca(int x,int y)
41 {
42     if(d[x]<d[y]) swap(x,y);
43     Dec(i,18,0) if(d[f[x][i]]>=d[y]) x=f[x][i];
44     if(x==y) return x;
45     Dec(i,18,0) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
46     return f[x][0];
47 }
48 void ins(int x,int &y,int l,int r,int p)
49 {
50     if(!y) y=++ct;
51     if(l==r) return (void)(s[y]=1);
52     if(p<=mid) rc[y]=rc[x],ins(lc[x],lc[y],l,mid,p);
53     else lc[y]=lc[x],ins(rc[x],rc[y],mid+1,r,p);
54     s[y]=s[lc[y]]+s[rc[y]];
55 }
56 int qry(int x,int l,int r,int L,int R)
57 {
58     if(L<=l&&r<=R) return s[x];
59     int t=0;
60     if(L<=mid) t+=qry(lc[x],l,mid,L,R);
61     if(mid<R) t+=qry(rc[x],mid+1,r,L,R);
62     return t;
63 }
64 int qrypath(int rt,int x,int y)
65 {
66     int t=0;
67     while(top[x]!=top[y])
68     {
69         if(d[top[x]]<d[top[y]]) swap(x,y);
70         t+=qry(rt,1,n,id[top[x]],id[x]);
71         x=f[top[x]][0];
72     }
73     if(d[x]>d[y]) swap(x,y);
74     return t+qry(rt,1,n,id[x],id[y]);
75 }
76 int main()
77 {
78     // file();
79     n=qr(); int x;
80     For(i,1,n) if(x=qr()) g[x].push_back(i);
81     dfs1(1); dfs2(1,1);
82     m=qr(); int y,c,z,op,ans1=0,ans2=0;
83     For(i,1,m)
84     {
85         op=qr();
86         if(op==2) ins(rt[i-1],rt[i],1,n,id[qr()]);
87         else
88         {
89             x=qr(),y=qr(),c=qr(); z=lca(x,y);
90             ans1=d[x]+d[y]-2*d[z]+1;
91             ans2=qrypath(rt[i-c-1],x,y);
92             printf("%d %d\n", ans1,ans2);
93             rt[i]=rt[i-1];
94         }
95     }
96     return 0;
97 }
View Code

猜你喜欢

转载自www.cnblogs.com/uuuxxllj/p/10817439.html
今日推荐