bzoj3626

链剖。。。题解看hz的。。。。离线搞

  1 #include<bits/stdc++.h>
  2 #define lowbit(a) ((a)&(-(a)))
  3 #define l(a) ((a)<<1)
  4 #define r(a) ((a)<<1|1)
  5 #define clr(a,x) memset(a,x,sizeof(a))
  6 #define rep(i,l,r) for(int i=l;i<(r);i++)
  7 #define Rep(i,a) rep(i,0,e[a].size())
  8 typedef long long ll;
  9 using namespace std;
 10 int read()
 11 {
 12     char c=getchar();
 13     int ans=0,f=1;
 14     while(!isdigit(c)){
 15         if(c=='-') f=-1;
 16         c=getchar();
 17     }
 18     while(isdigit(c)){
 19         ans=ans*10+c-'0';
 20         c=getchar();
 21     }
 22     return ans*f;
 23 }
 24 struct node{
 25     int l,r,sum,add;
 26 };
 27 struct query{
 28     int x,p;
 29     bool f;
 30     inline bool operator<(const query&A)const{
 31         return x<A.x;
 32     }
 33 };
 34 const int maxn=50009,mod=201314;
 35 int ans[maxn],n,m,dfstime=0,Top,g[maxn],size[maxn],f[maxn],son[maxn],top[maxn],dep[maxn],id[maxn];
 36 query q[maxn<<1];
 37 node x[maxn<<2];
 38 vector<int>e[maxn];
 39 void dfs(int k){
 40     size[k]=1;
 41     Rep(i,k){
 42         int to=e[k][i];
 43         if(to==f[k]) continue;
 44         f[to]=k;
 45         dep[to]=dep[k]+1;
 46         dfs(to);
 47         size[k]+=size[to];
 48         if(!son[k]||size[son[k]]<size[to]) son[k]=to;
 49     }
 50 }
 51 void Dfs(int k){
 52     top[k]=Top;
 53     id[k]=++dfstime;
 54     if(son[k]) Dfs(son[k]);
 55     Rep(i,k){
 56         int to=e[k][i];
 57         if(!id[to]) Dfs(Top=to);
 58     }
 59 }
 60 void maintain(int k){
 61     x[k].sum=x[l(k)].sum+x[r(k)].sum;
 62 }
 63 void pushdown(int k){
 64     if(x[k].l!=x[k].r&&x[k].add){
 65         x[l(k)].sum+=(x[l(k)].r-x[l(k)].l+1)*x[k].add;
 66         x[r(k)].sum+=(x[r(k)].r-x[r(k)].l+1)*x[k].add;
 67         x[l(k)].add+=x[k].add;
 68         x[r(k)].add+=x[k].add;
 69     }
 70     x[k].add=0;
 71 }
 72 void build(int k,int l,int r){
 73     x[k].l=l,x[k].r=r,x[k].sum=x[k].add=0;
 74     if(l==r) return;
 75     int mid=(l+r)>>1;
 76     build(l(k),l,mid);
 77     build(r(k),mid+1,r);
 78     maintain(k);
 79 }
 80 void modify(int k,int l,int r,int t){
 81     pushdown(k);
 82     if(x[k].l==l&&x[k].r==r){
 83         x[k].sum+=(r-l+1)*t;
 84         x[k].add+=t;
 85         return;
 86     }
 87     int mid=(x[k].l+x[k].r)>>1;
 88     if(r<=mid) modify(l(k),l,r,t);
 89     else if(l>mid) modify(r(k),l,r,t);
 90     else{
 91         modify(l(k),l,mid,t);
 92         modify(r(k),mid+1,r,t);
 93     }
 94     maintain(k);
 95 }
 96 int find(int k,int l,int r){
 97     pushdown(k);
 98     if(x[k].l==l&&x[k].r==r) return x[k].sum;
 99     int mid=(x[k].l+x[k].r)>>1;
100     if(r<=mid) return find(l(k),l,r);
101     if(l>mid) return find(r(k),l,r);
102     return (find(l(k),l,mid)+find(r(k),mid+1,r));
103 }
104 void add(int u,int v,int t){
105     while(top[u]!=top[v]){
106         if(dep[top[u]]<dep[top[v]]) swap(u,v);
107         modify(1,id[top[u]],id[u],t);
108         u=f[top[u]];
109     }
110     if(dep[u]>dep[v]) swap(u,v);
111     modify(1,id[u],id[v],t);
112 }
113 int sum(int u,int v){
114     int ans=0;
115     while(top[u]!=top[v]){
116         if(dep[top[u]]<dep[top[v]]) swap(u,v);
117         ans+=find(1,id[top[u]],id[u]);
118         u=f[top[u]];
119     }
120     if(dep[u]>dep[v]) swap(u,v);
121     ans+=find(1,id[u],id[v]);
122     return ans%mod;
123 }
124 void init(){
125     dep[0]=1;
126     dfs(0);
127     Dfs(Top=0);
128     build(1,1,n);
129 }
130 int main()
131 {    
132     n=read(),m=read();
133     rep(i,1,n){
134         int to=read();
135         e[to].push_back(i);
136         e[i].push_back(to);
137     }
138     init();
139     int cnt=0;
140     rep(i,0,m){
141         int l=read(),r=read();g[i]=read();
142         q[cnt].x=l-1;q[cnt].p=i;q[cnt++].f=0;
143         q[cnt].x=r;q[cnt].p=i;q[cnt++].f=1;
144     }
145     m<<=1;
146     sort(q,q+m);
147     cnt=-1;
148     rep(i,0,m){
149         while(cnt<q[i].x){    
150             cnt++;
151             add(cnt,0,1);
152         }
153         int t=sum(g[q[i].p],0);
154         ans[q[i].p]=ans[q[i].p]+t*(q[i].f?1:-1);
155     }
156     rep(i,0,m>>1) printf("%d\n",(ans[i]+mod)%mod);
157     return 0;
158 }
View Code

3626: [LNOI2014]LCA

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 947  Solved: 325
[Submit][Status][Discuss]

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。


 

 

Source

[Submit][Status][Discuss]
posted @ 2015-08-13 17:07  ChenThree  阅读(220)  评论(0编辑  收藏  举报