bzoj 3626: [LNOI2014]LCA
把区间排序,可以发现直接往点上到根搞一下值(每来一个数,路径上就加1),那么最后的答案可以差分一下,而且deep[lca]就可以直接查询z点到根的和。
1 #include<bits/stdc++.h> 2 #define N 200005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 const int mod=201314; 14 struct data{int id,p; bool flag;} a[N]; 15 struct seg{int size,tag,sum,l,r;} t[N<<1]; 16 struct node{int ans1,ans2,z;} q[N]; 17 struct edge{int next,to;} e[N]; 18 int n,m,cnt,dfn; 19 int son[50005],head[50005],fa[50005],belong[50005],pl[50005],deep[50005]; 20 bool cmp(data a, data b) {return a.p<b.p;} 21 void insert(int x, int y){e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;} 22 void dfs1(int x) 23 { 24 son[x]=1; 25 for (int i=head[x];i;i=e[i].next) 26 { 27 if (e[i].to==fa[x]) continue; 28 deep[e[i].to]=deep[x]+1; 29 fa[e[i].to]=x; 30 dfs1(e[i].to); 31 son[x]+=son[e[i].to]; 32 } 33 } 34 void dfs2(int x, int chain) 35 { 36 belong[x]=chain; pl[x]=++dfn; 37 int k=n; 38 for (int i=head[x];i;i=e[i].next) 39 if (e[i].to!=fa[x] && son[e[i].to]>son[k]) 40 k=e[i].to; 41 if (k!=n) dfs2(k,chain); 42 for (int i=head[x];i;i=e[i].next) 43 if (e[i].to!=fa[x] && e[i].to!=k) 44 dfs2(e[i].to,e[i].to); 45 } 46 void pushdown(int k) 47 { 48 if (t[k].l==t[k].r || !t[k].tag) return; 49 int tmp=t[k].tag%mod; t[k].tag=0; 50 t[k<<1].sum+=t[k<<1].size*tmp; 51 t[k<<1|1].sum+=t[k<<1|1].size*tmp; 52 t[k<<1].tag+=tmp; t[k<<1|1].tag+=tmp; 53 } 54 void update(int k) 55 { 56 t[k].sum=t[k<<1].sum+t[k<<1|1].sum; t[k].sum%=mod; 57 } 58 void build(int k, int l, int r) 59 { 60 t[k].l=l; t[k].r=r; t[k].size=r-l+1; 61 if (l==r) return; 62 int mid=l+r>>1; 63 build(k<<1,l,mid); build(k<<1|1,mid+1,r); 64 } 65 void change(int k, int x, int y) 66 { 67 pushdown(k); 68 int l=t[k].l,r=t[k].r; 69 if (l==x && y==r) 70 { 71 t[k].tag++; t[k].sum+=t[k].size; 72 return; 73 } 74 int mid=l+r>>1; 75 if (y<=mid) change(k<<1,x,y); 76 else if (x>mid) change(k<<1|1,x,y); 77 else { 78 change(k<<1,x,mid); change(k<<1|1,mid+1,y); 79 } 80 update(k); 81 } 82 int ask(int k, int x, int y) 83 { 84 pushdown(k); 85 int l=t[k].l,r=t[k].r; 86 if (l==x && y==r) return t[k].sum; 87 int mid=l+r>>1; 88 if (y<=mid) return ask(k<<1,x,y); 89 else if (x>mid) return ask(k<<1|1,x,y); 90 else return ask(k<<1,x,mid)+ask(k<<1|1,mid+1,y); 91 } 92 void solve_change(int x, int y) 93 { 94 while (belong[x]!=belong[y]) 95 { 96 change(1,pl[belong[x]],pl[x]); 97 x=fa[belong[x]]; 98 } 99 change(1,pl[y],pl[x]); 100 } 101 int solve_ask(int x, int y) 102 { 103 int sum=0; 104 while (belong[x]!=belong[y]) 105 { 106 sum+=ask(1,pl[belong[x]],pl[x])%mod; 107 sum%=mod; 108 x=fa[belong[x]]; 109 } 110 sum+=ask(1,pl[y],pl[x]); sum%=mod; 111 return sum; 112 } 113 int main() 114 { 115 n=ra(); m=ra(); 116 for (int i=1; i<n; i++) insert(ra(),i); 117 int tot=0; 118 for (int i=1; i<=m; i++) 119 { 120 int l=ra(),r=ra(); q[i].z=ra(); 121 a[++tot].p=l-1; a[tot].id=i; a[tot].flag=0; 122 a[++tot].p=r; a[tot].id=i; a[tot].flag=1; 123 } 124 build(1,1,n); 125 sort(a+1,a+tot+1,cmp); 126 dfs1(0); dfs2(0,0); 127 int now=-1; 128 for (int i=1; i<=tot; i++) 129 { 130 while (now<a[i].p) 131 { 132 now++; 133 solve_change(now,0); 134 } 135 int t=a[i].id; 136 if (!a[i].flag) q[t].ans1=solve_ask(q[t].z,0); 137 else q[t].ans2=solve_ask(q[t].z,0); 138 } 139 for (int i=1; i<=m; i++) 140 printf("%d\n",(q[i].ans2-q[i].ans1+mod)%mod); 141 return 0; 142 }