• 解题:LNOI 2014 LCA


    题面

    这题有点意思

    转化问题,我们把询问区间的点到根链加,再查询询问点到根的权值和就是每个询问的答案。

    然后如果你数据结构没学傻只需要差分一下就可以扫一遍出解了

      1 #include<cstdio>
      2 #include<vector>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define vpii vector<pair<int,int> >
      6 #define vpit vector<pair<int,int> >::iterator 
      7 using namespace std;
      8 const int N=50005,M=200005,mod=201314;
      9 int p[N],noww[M],goal[M],val[M],laz[M],siz[N];
     10 int far[N],dep[N],imp[N],dfn[N],top[N],ans[N];
     11 int n,q,t1,t2,t3,cnt,tot; vpii lp[N],rp[N];
     12 void Add(int &x,int y)
     13 {
     14     x+=y;
     15     if(x>=mod) x-=mod;
     16 }
     17 void Link(int f,int t)
     18 {//printf("Link %d with %d",f,t);
     19     noww[++cnt]=p[f];
     20     goal[cnt]=t,p[f]=cnt;
     21     noww[++cnt]=p[t];
     22     goal[cnt]=f,p[t]=cnt;
     23 }
     24 void Release(int nde,int l,int r)
     25 {
     26     if(laz[nde])
     27     {
     28         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1,&lz=laz[nde];
     29         val[ls]+=lz*(mid-l+1),laz[ls]+=lz;
     30         val[rs]+=lz*(r-mid),laz[rs]+=lz,lz=0;
     31     }
     32 }
     33 void Change(int nde,int l,int r,int ll,int rr,int tsk)
     34 {
     35     if(l>rr||r<ll)
     36         return ;
     37     else if(l>=ll&&r<=rr)
     38         val[nde]+=tsk*(r-l+1),laz[nde]+=tsk;
     39     else 
     40     {
     41         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde,l,r);
     42         Change(ls,l,mid,ll,rr,tsk),Change(rs,mid+1,r,ll,rr,tsk);
     43         val[nde]=val[ls]+val[rs];
     44     }
     45 }
     46 int Query(int nde,int l,int r,int ll,int rr)
     47 {
     48     if(l>rr||r<ll)
     49         return 0;
     50     else if(l>=ll&&r<=rr)
     51         return val[nde];
     52     else 
     53     {
     54         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde,l,r);
     55         return Query(ls,l,mid,ll,rr)+Query(rs,mid+1,r,ll,rr);
     56     }
     57 }
     58 void DFS(int nde,int fth,int dth)
     59 {
     60     int tmp=0;
     61     siz[nde]=1,far[nde]=fth,dep[nde]=dth;
     62     for(int i=p[nde];i;i=noww[i])
     63         if(goal[i]!=fth)
     64         {
     65             DFS(goal[i],nde,dth+1);
     66             siz[nde]+=siz[goal[i]];
     67             if(siz[goal[i]]>tmp)
     68                 tmp=siz[goal[i]],imp[nde]=goal[i];
     69         }
     70 }
     71 void Decompose(int nde,int tpp)
     72 {
     73     dfn[nde]=++tot,top[nde]=tpp;
     74     if(imp[nde])
     75     {
     76         Decompose(imp[nde],tpp);
     77         for(int i=p[nde];i;i=noww[i])
     78             if(goal[i]!=imp[nde]&&goal[i]!=far[nde])
     79                 Decompose(goal[i],goal[i]);
     80     }
     81 }
     82 void Chain_Change(int x,int y,int v)
     83 {
     84     while(top[x]!=top[y])
     85     {
     86         if(dep[top[x]]<dep[top[y]]) swap(x,y);
     87         Change(1,1,n,dfn[top[x]],dfn[x],v),x=far[top[x]];
     88     }
     89     if(dep[x]>dep[y]) swap(x,y);
     90     Change(1,1,n,dfn[x],dfn[y],v);
     91 }
     92 int Chain_Query(int x,int y)
     93 {
     94     int ret=0;
     95     while(top[x]!=top[y])
     96     {
     97         if(dep[top[x]]<dep[top[y]]) swap(x,y);
     98         ret+=Query(1,1,n,dfn[top[x]],dfn[x]),x=far[top[x]];
     99     }
    100     if(dep[x]>dep[y]) swap(x,y);
    101     ret+=Query(1,1,n,dfn[x],dfn[y]); return ret;
    102 }
    103 int main()
    104 {
    105     scanf("%d%d",&n,&q);
    106     for(int i=2;i<=n;i++)
    107         scanf("%d",&t1),Link(t1+1,i);
    108     for(int i=1;i<=q;i++)
    109     {
    110         scanf("%d%d%d",&t1,&t2,&t3);
    111         lp[t1].push_back(make_pair(i,t3+1));
    112         rp[t2+1].push_back(make_pair(i,t3+1));
    113     }
    114     DFS(1,0,1),Decompose(1,1);
    115     for(int i=1;i<=n;i++)
    116     {
    117         Chain_Change(1,i,1);
    118         for(vpit it=lp[i].begin();it!=lp[i].end();it++)
    119             ans[it->first]-=Chain_Query(1,it->second);//,printf("%d-=%d
    ",it->first,Chain_Query(1,it->second));
    120         for(vpit it=rp[i].begin();it!=rp[i].end();it++)
    121             ans[it->first]+=Chain_Query(1,it->second);//,printf("%d+=%d
    ",it->first,Chain_Query(1,it->second));
    122     }
    123     for(int i=1;i<=q;i++)
    124         printf("%d
    ",ans[i]%mod);
    125     return 0;
    126 }
    View Code
  • 相关阅读:
    第十三周助教总结
    C语言I博客作业09
    第十二周助教总结
    C语言I博客作业08
    第十一周助教总结
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I作业07
    C语言I作业06
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10452039.html
Copyright © 2020-2023  润新知