• Tsinsen A1303. tree(伍一鸣) (LCT+处理标记)


    【题目链接】

        http://www.tsinsen.com/A1303

    【题意】

        给定一棵树,提供树上路径乘/加一个数,加边断边,查询路径和的操作。

    【思路】

        LCT+传标

        一次dfs构造LCT。

        LCT维护信息:v,sum,rev,add,mul,siz

        提取路径(u,v):evert(u)->Access(v),splay(v),此时以v为根的splay辅助树即u->v的路径,直接进行操作即可。

        关于下传标记:

            Hezecong神犇的总结

        对于一个节点的标记,始终保持该标记已作用在该节点上。

      给节点打标记后作用于该节点,每次传标,给儿子打上标记且作用于该儿子。

        对于覆盖类标记,直接覆盖即可。反转标记单独处理。

      对于非覆盖类标记,考虑操作先后:先下传乘法标记,然后下传加法标记。对于乘法下传,还需要作用在加法标记上。

    【代码】

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #define FOR(a,b,c) for(int a=b;a<=c;a++)
      5 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
      6 using namespace std;
      7 
      8 typedef long long ll;
      9 typedef unsigned int ul;
     10 const int N = 4e5+10;
     11 const int MOD = 51061;
     12 
     13 namespace LCT {
     14 
     15     struct Node {
     16         Node *ch[2],*fa;
     17         ul v,siz,rev,add,mul,sum;
     18         Node() ;
     19         //给当前结点打上标记 且更新当前结点 
     20         void mulv(int x) {
     21             mul=(mul*x)%MOD;
     22             v=(v*x)%MOD;
     23             add=(add*x)%MOD;
     24             sum=(sum*x)%MOD;
     25         }
     26         void addv(int x) {
     27             v=(v+x)%MOD;
     28             add=(add+x)%MOD;
     29             sum=(sum+siz*x)%MOD;
     30         }
     31         void reverse() {
     32             rev^=1;
     33             swap(ch[0],ch[1]);
     34         }
     35         //up push down
     36         void up_push() {
     37             if(fa->ch[0]==this||fa->ch[1]==this)
     38                 fa->up_push();
     39             if(mul^1) {                             //mul != 1
     40                 ch[0]->mulv(mul);
     41                 ch[1]->mulv(mul);
     42                 mul=1;
     43             }
     44             if(add) {
     45                 ch[0]->addv(add);
     46                 ch[1]->addv(add);
     47                 add=0;
     48             }
     49             if(rev) {
     50                 ch[0]->reverse();
     51                 ch[1]->reverse();
     52                 rev=0;
     53             }
     54         }
     55         void maintain() {
     56             siz=ch[0]->siz+ch[1]->siz+1;
     57             sum=(ch[0]->sum+ch[1]->sum+v)%MOD;
     58         }
     59     } *null=new Node, T[N];
     60     Node:: Node() {
     61         fa=ch[0]=ch[1]=null;
     62         add=rev=0,mul=siz=1;
     63         sum=v=0;
     64     }
     65     
     66     void rot(Node* o,int d) {
     67         Node *p=o->fa;
     68         p->ch[d]=o->ch[d^1];
     69         o->ch[d^1]->fa=p;
     70         o->ch[d^1]=p;
     71         o->fa=p->fa;
     72         if(p==p->fa->ch[0])
     73             p->fa->ch[0]=o;
     74         else if(p==p->fa->ch[1])
     75             p->fa->ch[1]=o;
     76         p->fa=o;
     77         p->maintain();
     78     }
     79     void splay(Node* o) {
     80         o->up_push();
     81         Node *nf,*nff;
     82         while(o->fa->ch[0]==o||o->fa->ch[1]==o) {
     83             nf=o->fa,nff=nf->fa;
     84             if(o==nf->ch[0]) {
     85                 if(nf==nff->ch[0]) rot(nf,0);
     86                 rot(o,0);
     87             } else {
     88                 if(nf==nff->ch[1]) rot(nf,1);
     89                 rot(o,1);
     90             }
     91         }
     92         o->maintain();
     93     }
     94     void Access(Node* o) {
     95         Node* son=null;
     96         while(o!=null) {
     97             splay(o);
     98             o->ch[1]=son;
     99             o->maintain();
    100             son=o; o=o->fa;
    101         }
    102     }
    103     void evert(Node* o) {
    104         Access(o); 
    105         splay(o);
    106         o->reverse();
    107     }
    108     void Link(Node *u,Node *v) {
    109         evert(u);
    110         u->fa=v;
    111     }
    112     void Cut(Node *u,Node *v) {
    113         evert(u);
    114         Access(v); splay(v);
    115         u->fa=v->ch[0]=null;
    116         v->maintain();
    117     }
    118 
    119 }
    120 using namespace LCT;
    121 
    122 struct Edge { int v,nxt;
    123 }e[N<<2];
    124 int en=1,front[N];
    125 void adde(int u,int v) {
    126     e[++en]=(Edge){v,front[u]}; front[u]=en;
    127 }
    128 
    129 ll read()
    130 {
    131     char c=getchar(); 
    132     ll f=1,x=0;
    133     while(!isdigit(c)) {
    134         if(c=='-') f=-1; 
    135         c=getchar();
    136     }
    137     while(isdigit(c))
    138         x=x*10+c-'0',
    139         c=getchar();
    140     return x*f;
    141 }
    142 
    143 int n,q;
    144 
    145 void build(int u,int fa) {
    146     T[u].sum=T[u].v=1;
    147     trav(u,i) {
    148         int v=e[i].v;
    149         if(v!=fa) {
    150             T[v].fa=&T[u];
    151             build(v,u);
    152         }
    153     }
    154 }
    155 
    156 int main()
    157 {
    158     null->siz=null->mul=0;
    159     n=read(),q=read();
    160     for(int i=1;i<n;i++) {
    161         int u=read(),v=read();
    162         adde(u,v),adde(v,u);
    163     }
    164     build(1,-1);
    165     char op[2];
    166     int u,v,x,y;
    167     while(q--) {
    168         scanf("%s",&op);
    169         u=read(),v=read();
    170         if(op[0]=='+' || op[0]=='*') {
    171             x=read();
    172             evert(&T[u]);
    173             Access(&T[v]); splay(&T[v]);
    174             if(op[0]=='+') T[v].addv(x);
    175             else T[v].mulv(x);
    176         } else
    177         if(op[0]=='-') {
    178             x=read(),y=read();
    179             Cut(&T[u],&T[v]);
    180             Link(&T[x],&T[y]);
    181         } else {
    182             evert(&T[u]);
    183             Access(&T[v]); splay(&T[v]);
    184             printf("%d
    ",T[v].sum);
    185         }
    186     }
    187     return 0;
    188 }
  • 相关阅读:
    Spring-Lesson2
    Spring-Lesson1
    三十九:WEB漏洞-XXE&XML之利用检测绕过全解
    三十八:WEB漏洞-反序列化之PHP&JAVA全解(下)
    三十七:WEB漏洞-反序列化之PHP&JAVA全解(上)
    三十六:WEB漏洞-逻辑越权之验证码与Token接口
    cookie,session,token傻傻分不清
    三十五:WEB漏洞-逻辑漏洞之找回机制及接口安全
    三十四:WEB漏洞之登录脆弱及支付篡改
    三十三:WEB漏洞-逻辑越权之水平垂直越权
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5320299.html
Copyright © 2020-2023  润新知