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 }

 

posted @ 2017-03-01 08:41  ws_ccd  阅读(242)  评论(0编辑  收藏  举报