1. 程式人生 > >BZOJ2631 tree(伍一鳴) LCT 秘制標記

BZOJ2631 tree(伍一鳴) LCT 秘制標記

case unsigned fin ++ fine cstring name size ios

這個題一看就是裸地LCT嘛,但是我wa了好幾遍,這秘制標記......

註意事項:I.*對+有貢獻 II.先下傳*再下傳+(因為我們已經維護了+,不能再讓*對+產生貢獻)III.維護+用到size

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 100005
#define P 51061
using namespace std;
inline unsigned int read()
{
    unsigned int sum=0;
    char ch=getchar();
    
while(ch<0||ch>9)ch=getchar(); while(ch>=0&&ch<=9) { sum=(sum<<1)+(sum<<3)+ch-0; ch=getchar(); } return sum; } struct LCT { struct Node { Node *ch[2],*f; unsigned int key,multi,pluss,sum,size; bool rev;
void pushup() { sum=(key+ch[0]->sum+ch[1]->sum)%P; size=ch[0]->size+1+ch[1]->size; } }null[MAXN]; void swap(Node *&x,Node *&y) { Node *temp=x; x=y; y=temp; } void pushdown(Node *p) { if(p->rev) { p
->ch[0]->rev^=1; p->ch[1]->rev^=1; swap(p->ch[0],p->ch[1]); p->rev=0; } if(p->multi!=1) { p->ch[0]->sum=(p->ch[0]->sum*p->multi)%P; p->ch[0]->key=(p->ch[0]->key*p->multi)%P; p->ch[0]->pluss=(p->ch[0]->pluss*p->multi)%P; p->ch[0]->multi=(p->ch[0]->multi*p->multi)%P; p->ch[1]->sum=(p->ch[1]->sum*p->multi)%P; p->ch[1]->key=(p->ch[1]->key*p->multi)%P; p->ch[1]->pluss=(p->ch[1]->pluss*p->multi)%P; p->ch[1]->multi=(p->ch[1]->multi*p->multi)%P; p->multi=1; } if(p->pluss) { if(p->ch[1]!=null) { p->ch[1]->sum=(p->ch[1]->sum+p->pluss*p->ch[1]->size)%P; p->ch[1]->key=(p->ch[1]->key+p->pluss)%P; p->ch[1]->pluss=(p->ch[1]->pluss+p->pluss)%P; } if(p->ch[0]!=null) { p->ch[0]->sum=(p->ch[0]->sum+p->pluss*p->ch[0]->size)%P; p->ch[0]->key=(p->ch[0]->key+p->pluss)%P; p->ch[0]->pluss=(p->ch[0]->pluss+p->pluss)%P; } p->pluss=0; } } void Init() { null->ch[1]=null->ch[0]=null->f=null; for(unsigned int i=1;i<MAXN;i++) null[i].ch[0]=null[i].ch[1]=null[i].f=null,null[i].sum=null[i].key=null[i].multi=1,null[i].pluss=0; } bool isroot(Node *p) { return p->f->ch[0]!=p&&p->f->ch[1]!=p; } unsigned int get(Node *p) { return p->f->ch[1]==p; } void rotate(Node *p) { Node *fa=p->f,*pa=fa->f; unsigned int j=get(p); if(!isroot(fa))pa->ch[get(fa)]=p; if((fa->ch[j]=p->ch[j^1])!=null)fa->ch[j]->f=fa; fa->f=p; p->f=pa; p->ch[j^1]=fa; fa->pushup(); p->pushup(); } void spaly(Node *p) { pushdown(p); for(Node *fa=p->f;!isroot(p);rotate(p),fa=p->f) if(!isroot(fa)) { pushdown(fa->f),pushdown(fa),pushdown(p); rotate(get(fa)==get(p)?fa:p); } else pushdown(fa),pushdown(p); } void expose(Node *x) { Node *y=null; while(x!=null) { spaly(x); x->ch[1]=y; x->pushup(); y=x; x=x->f; } } void make_root(Node *p) { expose(p); spaly(p); p->rev^=1; } void cut(unsigned int a,unsigned int b) { Node *x=null+a,*y=null+b; make_root(x); expose(y); spaly(y); y->ch[0]->f=null; y->ch[0]=null; y->pushup(); } void link(unsigned int a,unsigned int b) { Node *x=null+a,*y=null+b; make_root(x); x->f=y; } void up(unsigned int a,unsigned int b,unsigned int c) { Node *x=null+a,*y=null+b; make_root(x); expose(y); spaly(y); y->pluss=(y->pluss+c)%P; y->key=(y->key+c)%P; y->sum=(y->sum+y->size*c)%P; } void UUP(unsigned int a,unsigned int b,unsigned int c) { Node *x=null+a,*y=null+b; make_root(x); expose(y); spaly(y); y->multi=(y->multi*c)%P; y->key=(y->key*c)%P; y->sum=(y->sum*c)%P; y->pluss=(y->pluss*c)%P; } unsigned int query(unsigned int a,unsigned int b) { Node *x=null+a,*y=null+b; make_root(x); expose(y); spaly(y); return y->sum; } }YY; int main() { YY.Init(); unsigned int n=read(),m=read(); for(unsigned int i=1;i<n;i++) { unsigned int x=read(),y=read(); YY.link(x,y); } for(unsigned int i=1,x,y,z,a,b;i<=m;i++) { char ch; cin>>ch; x=read(),y=read(); switch(ch) { case *:z=read(); YY.UUP(x,y,z); break; case +:z=read(); YY.up(x,y,z); break; case -:a=read(),b=read(); YY.cut(x,y); YY.link(a,b); break; case /:printf("%d\n",YY.query(x,y)); break; } } return 0; }

BZOJ2631 tree(伍一鳴) LCT 秘制標記