BZOJ3626 [LNOI2014]LCA

Description

给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。
设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。
有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[LCA(i,z)]。
(即,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和)

Input

第一行2个整数n q。
接下来n-1行,分别表示点1到点n-1的父节点编号。
接下来q行,每行3个整数l r z。

Output

输出q行,每行表示一个询问的答案。每个答案对201314取模输出

Sample Input

5 2
0
0
1
1
1 4 3
1 4 2

Sample Output

8
5

HINT

共5组数据,n与q的规模分别为10000,20000,30000,40000,50000。

未解决

bzoj上WA了,和qt666拍了极限数据没WA,我还能干什么

  1 #include <iostream>
  2 #include <iomanip>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 #include <cmath>
  6 #include <cstring>
  7 #include <string>
  8 #include <algorithm>
  9 #define int long long
 10 #define RG register
 11 const int N = 500000;
 12 const int mod=201314;
 13 
 14 using namespace std;
 15 
 16 int gi()
 17 {
 18   int x=0,flag=1;
 19   char ch=getchar();
 20   while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
 21   while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
 22   return x*flag;
 23 }
 24 
 25 int fa[N],c[N][2],lazy[N],w[N],rev[N],st[N],siz[N],f[N];
 26 long long ans[N];
 27 
 28 struct date{
 29     int r,z,i,x;
 30     bool operator < (const date a) const {
 31         return r<a.r;
 32     }
 33 }qu[N];
 34 
 35 int isroot(int x){
 36     return c[fa[x]][0]!=x && c[fa[x]][1]!=x;
 37 }
 38 
 39 void pushdown(int x){
 40     if (lazy[x]){
 41         w[c[x][0]]+=lazy[x]*siz[c[x][0]],f[c[x][0]]+=lazy[x];
 42         w[c[x][1]]+=lazy[x]*siz[c[x][1]],f[c[x][1]]+=lazy[x];
 43         lazy[c[x][0]]+=lazy[x],lazy[c[x][1]]+=lazy[x];
 44         lazy[x]=0;
 45     }
 46     if (rev[x]==0) return;
 47     rev[x]^=1,rev[c[x][0]]^=1,rev[c[x][1]]^=1;
 48     swap(c[x][0],c[x][1]);
 49     return;
 50 }
 51 
 52 void update(int x){
 53     siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;
 54     w[x]=w[c[x][0]]+w[c[x][1]]+f[x];
 55     return;
 56 }
 57 
 58 void rotate(int x){
 59     int y=fa[x],z=fa[y],l,r;
 60     if (c[y][0]==x) l=0;
 61     else l=1;r=l^1;
 62     if (!isroot(y))
 63         if (c[z][0]==y) c[z][0]=x;
 64         else c[z][1]=x;
 65     fa[c[x][r]]=y,fa[y]=x,fa[x]=z;
 66     c[y][l]=c[x][r],c[x][r]=y;
 67     update(y),update(x);
 68     return;
 69 }
 70 
 71 void splay(int x){
 72     int tot=0;st[++tot]=x;
 73     for (RG int i=x; !isroot(i); i=fa[i]) st[++tot]=fa[i];
 74     for (RG int i=tot; i; --i) pushdown(st[i]);
 75     while(!isroot(x)){
 76         int y=fa[x],z=fa[y];
 77         if (!isroot(y))
 78             if (c[y][0]==x ^ c[z][0]==y) rotate(x);
 79             else rotate(y);
 80         rotate(x);
 81     }
 82     return;
 83 }
 84 
 85 void access(int x){
 86     int t=0;
 87     while(x){
 88         splay(x);
 89         c[x][1]=t;update(x);
 90         t=x,x=fa[x];
 91     }
 92 }
 93 
 94 void rever(int x){
 95     access(x),splay(x),rev[x]^=1;
 96     return;
 97 }
 98 
 99 main(){
100     freopen("lct.in","r",stdin);
101     freopen("lct.out","w",stdout);
102     int n=gi(),q=gi(),head=1;
103     siz[1]=1;
104     for (RG int i=2; i<=n; ++i) fa[i]=gi()+1,siz[i]=1;
105     for (RG int i=1; i<=q; ++i){
106         int l=gi(),r=gi()+1,z=gi()+1;
107         qu[i]=(date){l,z,i,-1};
108         qu[i+q]=(date){r,z,i,1};
109     }
110     sort(qu+1,qu+2*q+1);q*=2;
111     for (RG int i=1; i<=n; ++i){
112         rever(1),access(i),splay(i);
113         ++lazy[i],++f[i],w[i]+=siz[i];
114         while(qu[head].r<=i && head<=q){
115             int z=qu[head].z;
116             rever(1),access(z),splay(z);
117             update(z);
118             ans[qu[head].i]+=w[qu[head].z]*qu[head].x;
119             ++head;
120         }
121     }
122     q/=2;
123     for (RG int i=1; i<=q; ++i) printf("%lld
",(ans[i]+mod)%mod);
124     return 0;
125 }

--------------------------------------------------------------------------------------------------------------------------------------------

很尴尬,用主席树在线做就A掉了

 1 #include <iostream>
 2 #include <iomanip>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <string>
 7 #include <cstring>
 8 #include <algorithm>
 9 #define RG register
10 #define ll long long
11 const int N = 110000;
12 const int M = 6300000;
13 
14 using namespace std;
15 
16 int st[N][2],dis[N],son[N],siz[N],top[N],id[N];
17 int fa[N],nn[N][2],head[N],cnt,rt[N];
18 struct date{int l,r,lazy;ll s;}tr[M];
19 
20 void dfs1(int xh,int fu){
21     fa[xh]=fu,dis[xh]=dis[fu]+1;
22     for (RG int i=head[xh]; i; i=nn[i][0]){
23         if (nn[i][1]==fu) continue;
24         dfs1(nn[i][1],xh);
25         if (siz[nn[i][1]]>siz[son[xh]]) son[xh]=nn[i][1];
26         siz[xh]+=siz[nn[i][1]];
27     }
28     ++siz[xh];
29     return;
30 }
31 
32 void dfs2(int xh,int tp){
33     id[xh]=++cnt,top[xh]=tp;
34     if (son[xh]) dfs2(son[xh],tp);
35     for (RG int i=head[xh]; i; i=nn[i][0]){
36         if (nn[i][1]==fa[xh] || nn[i][1]==son[xh]) continue;
37         dfs2(nn[i][1],nn[i][1]);
38     }
39     return;
40 }
41 
42 void update(int &t,int l,int r,int ql,int qr){
43     tr[++cnt]=tr[t],t=cnt;
44     if (ql<=l && r<=qr) {++tr[t].lazy,tr[t].s+=(r-l+1);return;}
45     int mid=(l+r)>>1;
46     if (ql<=mid) update(tr[t].l,l,mid,ql,qr);
47     if (qr>mid) update(tr[t].r,mid+1,r,ql,qr);
48     tr[t].s=tr[tr[t].l].s+tr[tr[t].r].s+tr[t].lazy*(r-l+1);
49     return;
50 }
51 
52 int query(int x,int l,int r,int ql,int qr,int la){
53     if (ql<=l && r<=qr) return (r-l+1)*la+tr[x].s;
54     int mid=(l+r)>>1,ans=0;la+=tr[x].lazy;
55     if (ql<=mid) ans+=query(tr[x].l,l,mid,ql,qr,la);
56     if (qr>mid) ans+=query(tr[x].r,mid+1,r,ql,qr,la);
57     return ans;
58 }
59 
60 int gi(){
61     char ch=getchar();int x=0;
62     while(ch<'0' || ch>'9') ch=getchar();
63     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
64     return x;
65 }
66 
67 main(){
68     int n=gi(),q=gi();
69     for (RG int i=2; i<=n; ++i){
70         int l=gi()+1;
71         nn[++cnt][1]=l,nn[cnt][0]=head[i],head[i]=cnt;
72         nn[++cnt][1]=i,nn[cnt][0]=head[l],head[l]=cnt;
73     }
74     cnt=0;
75     dfs1(1,0),dfs2(1,1);
76     cnt=0;
77     for (RG int i=1; i<=n; ++i){
78         int tot=0,x=i;
79         while(top[x]!=1){
80             st[++tot][0]=id[top[x]],st[tot][1]=id[x];
81             x=fa[top[x]];
82         }
83         rt[i]=rt[i-1],st[++tot][0]=1,st[tot][1]=id[x];
84         for (RG int j=1; j<=tot; ++j) update(rt[i],1,n,st[j][0],st[j][1]);
85     }
86     for (RG int i=1; i<=q; ++i){
87         int tot=0,l=gi()+1,r=gi()+1,x=gi()+1;
88         while(top[x]!=1){
89             st[++tot][0]=id[top[x]],st[tot][1]=id[x];
90             x=fa[top[x]];
91         }
92         st[++tot][0]=1,st[tot][1]=id[x];
93         long long ans=0;
94         for (RG int i=1; i<=tot; ++i)
95             ans+=query(rt[r],1,n,st[i][0],st[i][1],0)-query(rt[l-1],1,n,st[i][0],st[i][1],0);
96         printf("%lld
",ans%201314);
97     }
98     return 0;
99 }
原文地址:https://www.cnblogs.com/cjk2001/p/6489844.html