zoukankan      html  css  js  c++  java
  • BZOJ 2631: tree

    题目链接:

      TP

    题解:

      emmmm,刚掌握了$lazy-zag$,调了好久233

      一开始是因为直接让当前节点的$sum$等于两儿子之和,发现只出0,意识到还有本节点的价值……

      然后发现这样子还是不太对,意识到下传标记的时候不止要给儿子点权、$lazy$标记 乘/加 标记,还要给儿子的$sum$乘/加。

      然后还是不对……发现自己给儿子$sum$传$add$的时候没有乘儿子树的大小……

      终于过了……

    代码:

      

      1 #define Troy
      2  
      3 #include "bits/stdc++.h"
      4  
      5 using namespace std;
      6  
      7 const int N=1e5+5,mod=51061;
      8  
      9 inline int read(){
     10     int s=0,k=1;char ch=getchar();
     11     while(ch<'0'|ch>'9')    ch=='-'?k=-1:0,ch=getchar();
     12     while(ch>47&ch<='9')    s=s*10+(ch^48),ch=getchar();
     13     return s*k;
     14 }
     15  
     16 #define size(t) (t?t->size:0)
     17 #define sz(t)   (t?t->sz:0)
     18 #define rev(t)  (t?t->rev^=1:0)
     19 #define mul(x,y)  (x*1ll*y>mod?x=x*1ll*y%mod:x=x*1ll*y)
     20 #define add(x,y)  (x=x+y,x>=mod?x-=mod:0)
     21  
     22 struct Node{
     23     Node *fa,*son[2];
     24     int sum,mul,add,rev,size,sz;
     25     Node(){fa=son[0]=son[1]=NULL;sum=size=mul=1,add=0,rev=0;}
     26     inline void update(){size=(sum*1ll+size(son[0])+size(son[1]));if(size>=mod) size%=mod;sz=1+sz(son[0])+sz(son[1]);}
     27     inline void pushdown(){
     28         if(rev){swap(son[0],son[1]);rev=0;
     29             rev(son[0]),rev(son[1]);
     30         }
     31         int t;
     32         if(son[0]){
     33             t=add*1ll*son[0]->sz%mod;
     34             mul(son[0]->size,mul),add(son[0]->size,t);
     35             mul(son[0]->sum,mul),add(son[0]->sum,add);
     36             mul(son[0]->mul,mul),mul(son[0]->add,mul);
     37             add(son[0]->add,add);
     38         }
     39         if(son[1]){
     40             t=add*1ll*son[1]->sz%mod;
     41             mul(son[1]->size,mul),add(son[1]->size,t);            
     42             mul(son[1]->sum,mul),add(son[1]->sum,add);
     43             mul(son[1]->mul,mul),mul(son[1]->add,mul);
     44             add(son[1]->add,add);
     45         }
     46         mul=1,add=0;
     47     }
     48 }*pool[N],*tmp[N],tree[N];int top;
     49  
     50 inline void init(){for(;top<N;++top)   pool[top]=tree+top;}
     51 inline void newNode(Node *&p,Node *f){p=pool[--top];*p=Node();p->fa=f;}
     52 inline void freeNode(Node *&p){pool[top++]=p,p=NULL;}
     53  
     54 int n,m;
     55 class LCT{
     56 public:
     57     Node *node[N];
     58     inline void init(int n){for(register int i=1;i<=n;++i)newNode(node[i],NULL);}
     59      
     60     #define son(p)  (p->fa->son[1]==p)
     61     #define is_root(p)  ((!p->fa)||(p->fa->son[0]!=p&&p->fa->son[1]!=p))
     62  
     63     inline void rotate(Node *p){
     64         int a=son(p)^1;Node *f=p->fa;
     65         f->son[a^1]=p->son[a];
     66         if(p->son[a])   p->son[a]->fa=f;
     67         p->fa=f->fa;
     68         if(!is_root(f))   p->fa->son[son(f)]=p;
     69         f->fa=p,p->son[a]=f,f->update(),p->update();
     70     }
     71  
     72     inline void splay(Node *&p){
     73         register int pos=0;
     74         for(Node *t=p;;t=t->fa){
     75             tmp[++pos]=t;
     76             if(is_root(t)) break;
     77         }
     78         for(;pos;--pos) tmp[pos]->pushdown();
     79         for(;!is_root(p);rotate(p))
     80             if(!is_root(p->fa)) rotate(son(p)==son(p->fa)?p->fa:p);
     81     }
     82  
     83     inline void access(Node *p){
     84         for(Node *pre=NULL;p;pre=p,p=p->fa)
     85             splay(p),p->son[1]=pre,p->update();
     86     }
     87  
     88     #define make_root(p) (access(p),splay(p),rev(p))
     89     #define mas(x,y) (make_root(x),access(y),splay(y))
     90  
     91     inline void cut(Node *x,Node *y){mas(x,y);x->fa=y->son[0]=NULL,y->update();} 
     92     inline void link(Node *x,Node *y){if(x->fa) swap(x,y);make_root(x),x->fa=y;}
     93     inline void link(int x,int y){link(node[x],node[y]);}
     94  
     95     inline void op_era(int x,int y,int nx,int ny){cut(node[x],node[y]),link(node[nx],node[ny]);}
     96     inline void op_plus(int x,int y,int val){
     97         mas(node[x],node[y]);
     98         add(node[y]->sum,val);
     99         add(node[y]->add,val);
    100     }
    101     inline void op_mul(int x,int y,int val){            
    102         mas(node[x],node[y]);        
    103         mul(node[y]->sum,val),mul(node[y]->mul,val);
    104         mul(node[y]->add,val);
    105     }
    106      
    107     inline void op_del(int x,int y){
    108         mas(node[x],node[y]); 
    109         printf("%d
    ",node[y]->size);
    110     }
    111 }lct;
    112  
    113 int main(){
    114     // freopen(".in","r",stdin);
    115     // freopen(".out","w",stdout);
    116     n=read(),m=read();
    117     init();
    118     lct.init(n);
    119     register int i,x,y,nx,ny;
    120     for(i=1;i^n;++i){
    121         x=read(),y=read();
    122         lct.link(x,y);
    123     }
    124     char opt[3];
    125     while(m--){
    126         scanf("%s",opt);x=read(),y=read();
    127         switch(opt[0]){
    128             case '*':lct.op_mul(x,y,read()%mod); break;
    129             case '+':lct.op_plus(x,y,read()%mod);break;
    130             case '-':nx=read(),ny=read();lct.op_era(x,y,nx,ny);break;
    131             case '/':lct.op_del(x,y);break;
    132         }
    133     }
    134 }
  • 相关阅读:
    LPT算法--时间调度问题
    Java语法学习1
    用JS动态显示文本
    用JS动态创建一个有序表(根据输入添加子列表项)
    邻接表链式结构的实现和顺序结构的实现
    HDU 1242 特殊化带结构体BFS
    POJ 1562深搜判断连体油田个数
    Uva 8道比较水的数论 (练练英语阅读理解)
    HDU 2024 C语言合法标识符(笑)
    再做POJ2406 KMPnext数组的运用
  • 原文地址:https://www.cnblogs.com/Troywar/p/8045754.html
Copyright © 2011-2022 走看看