• 【国家集训队2012】tree(伍一鸣)


    Description
    一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一: 
    + u v c:将u到v的路径上的点的权值都加上自然数c; 
    - u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树; 
    * u v c:将u到v的路径上的点的权值都乘上自然数c; 
    / u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。

    Input
    第一行两个整数n,q 
    接下来n-1行每行两个正整数u,v,描述这棵树 
    接下来q行,每行描述一个操作

    Output
    对于每个/对应的答案输出一行

    Sample Input
    3 2 
    1 2 
    2 3 
    * 1 3 4 
    / 1 1


    Sample Output
    4

    Hint
    数据规模: 
    10%的数据保证,1<=n,q<=2000 
    另外15%的数据保证,1<=n,q<=5 * 10^4,没有-操作,并且初始树为一条链 
    另外35%的数据保证,1<=n,q<=5 * 10^4,没有-操作 
    100%的数据保证,1<=n,q<=10^5,0<=c<=10^4


    正解:link-cut tree。

    毒瘤数据结构题,调了我一下午。。主要是加和乘的lazy标记,下放时如果是乘,那么加的那个标记也要同乘,并且要先下放乘的标记,再下放加的标记。

      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <cmath>
      9 #include <queue>
     10 #include <stack>
     11 #include <map>
     12 #include <set>
     13 #define inf (1<<30)
     14 #define r64 (51061)
     15 #define N (100010)
     16 #define il inline
     17 #define RG register
     18 #define uint unsigned int
     19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
     20 
     21 using namespace std;
     22 
     23 uint ch[N][2],fa[N],size[N],lazy[N],st[N],rev1[N],rev2[N],val[N],sum[N],n,q;
     24 char s[5];
     25 
     26 il uint gi(){
     27     RG uint x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     28     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
     29 }
     30 
     31 il void pushdown(RG uint x){
     32     RG uint &l=ch[x][0],&r=ch[x][1];
     33     if (lazy[x]) lazy[x]=0,lazy[l]^=1,lazy[r]^=1,swap(l,r);
     34     if (rev2[x]!=1){
     35     (val[l]*=rev2[x])%=r64,(val[r]*=rev2[x])%=r64;
     36     (sum[l]*=rev2[x])%=r64,(sum[r]*=rev2[x])%=r64;
     37     (rev1[l]*=rev2[x])%=r64,(rev1[r]*=rev2[x])%=r64;
     38     (rev2[l]*=rev2[x])%=r64,(rev2[r]*=rev2[x])%=r64,rev2[x]=1;
     39     }
     40     if (rev1[x]){
     41     (val[l]+=rev1[x])%=r64,(val[r]+=rev1[x])%=r64;
     42     (sum[l]+=rev1[x]*(size[l]%r64))%=r64,(sum[r]+=rev1[x]*(size[r]%r64))%=r64;
     43     (rev1[l]+=rev1[x])%=r64,(rev1[r]+=rev1[x])%=r64,rev1[x]=0;
     44     }
     45     return;
     46 }
     47 
     48 il void pushup(RG uint x){
     49     sum[x]=(sum[ch[x][0]]+sum[ch[x][1]]+val[x])%r64;
     50     size[x]=size[ch[x][0]]+size[ch[x][1]]+1; return;
     51 }
     52 
     53 il uint isroot(RG uint x){ return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; }
     54 
     55 il void rotate(RG uint x){
     56     RG uint y=fa[x],z=fa[y],k=ch[y][0]==x; if (!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;
     57     ch[y][k^1]=ch[x][k],fa[ch[x][k]]=y,ch[x][k]=y,fa[y]=x,pushup(y),pushup(x); return;
     58 }
     59 
     60 il void splay(RG uint x){
     61     RG uint top=0; st[++top]=x;
     62     for (RG uint i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
     63     while (top) pushdown(st[top--]);
     64     while (!isroot(x)){
     65     RG uint y=fa[x],z=fa[y];
     66     if (!isroot(y)){ if ((ch[z][0]==y)^(ch[y][0]==x)) rotate(x); else rotate(y); }
     67     rotate(x);
     68     }
     69     return;
     70 }
     71 
     72 il void access(RG uint x){ RG uint t=0; while (x) splay(x),ch[x][1]=t,pushup(x),t=x,x=fa[x]; return; }
     73 
     74 il void split(RG uint x){ access(x),splay(x); return; }
     75 
     76 il void makeroot(RG uint x){ split(x),lazy[x]^=1; return; }
     77 
     78 il void link(RG uint x,RG uint y){ makeroot(x),fa[x]=y; return; }
     79 
     80 il void cut(RG uint x,RG uint y){ makeroot(x),split(y),ch[y][0]=fa[x]=0,pushup(y); return; }
     81 
     82 il void add(RG uint x,RG uint y,RG uint v){
     83     makeroot(x),split(y),(rev1[y]+=v)%=r64,(val[y]+=v)%=r64,(sum[y]+=v*(size[y]%r64))%=r64; return;
     84 }
     85 
     86 il void times(RG uint x,RG uint y,RG uint v){
     87     makeroot(x),split(y),(rev1[y]*=v)%=r64,(rev2[y]*=v)%=r64,(val[y]*=v)%=r64,(sum[y]*=v)%=r64; return;
     88 }
     89 il uint query(RG uint x,RG uint y){ makeroot(x),split(y); return sum[y]; }
     90 
     91 il void work(){
     92     n=gi(),q=gi(); RG uint u,v,c; for (RG uint i=1;i<=n;++i) sum[i]=val[i]=rev2[i]=size[i]=1;
     93     for (RG uint i=1;i<n;++i) u=gi(),v=gi(),link(u,v);
     94     for (RG uint i=1;i<=q;++i){
     95     scanf("%s",s); if (s[0]=='+') u=gi(),v=gi(),c=gi(),add(u,v,c);
     96     if (s[0]=='-') u=gi(),v=gi(),cut(u,v),u=gi(),v=gi(),link(u,v);
     97     if (s[0]=='*') u=gi(),v=gi(),c=gi(),times(u,v,c);
     98     if (s[0]=='/'){ u=gi(),v=gi(); printf("%u
    ",query(u,v)); }
     99     }
    100     return;
    101 }
    102 
    103 int main(){
    104     File("tree");
    105     work();
    106     return 0;
    107 }
  • 相关阅读:
    开发流程
    团队模式
    android studio 中点击button加1或者减1
    登录注册界面的测试点
    用在线工具processOn画UML的用例图和时序图
    android studio中R文件丢失了
    第一次迭代任务
    WBS(work Breakdown Structure)
    #“速达” app NABCD分析
    “速达”app电梯演说
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6416559.html
Copyright © 2020-2023  润新知