2631: tree LCT第二题

来源:互联网 发布:otg软件下载 编辑:程序博客网 时间:2024/05/16 07:34

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

权限题差评。。
这题还是一个模板题。。
但是我才第二题就陷入了无限调试,最后发现pushdown写错了
终于知道rev的重要性了

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<stack>typedef unsigned int Int;using namespace std;const int N=100005;const int MOD=51061;struct qq{    int son[2],fa;    bool rev;    Int add,mul;    Int c;//权值和    Int d;//自己的值     Int tot;//人数     qq bt ()    {        son[0]=son[1]=fa=rev=add=0;mul=1;        c=1;d=1;tot=1;    };}s[N];int n,q;void cal (int x,int m,int a){    if (x==0) return ;    s[x].d=(s[x].d*m+a)%MOD;    s[x].c=(s[x].c*m+a*s[x].tot)%MOD;    s[x].add=(s[x].add*m+a)%MOD;    s[x].mul=(s[x].mul*m)%MOD;}void update (int x)//更新这个节点的信息{    int s1=s[x].son[0],s2=s[x].son[1];    s[x].tot=s[s1].tot+s[s2].tot+1;    s[x].c=(s[s1].c+s[s2].c+s[x].d)%MOD;}void Push_down (int x){    int s1=s[x].son[0],s2=s[x].son[1];    if (s[x].rev)    {        s[x].rev=false;        s[s1].rev^=1;s[s2].rev^=1;        swap(s[x].son[0],s[x].son[1]);    }    int m=s[x].mul,a=s[x].add;    s[x].mul=1;s[x].add=0;    if (m!=1||a!=0){cal(s1,m,a);cal(s2,m,a);}}bool Is_root(int x){  if((s[s[x].fa].son[0]!=x)&&(s[s[x].fa].son[1]!=x)) return true;  return false;}void rotate (int x){    int y=s[x].fa,z=s[y].fa;    int r,R,f,w;    if (s[y].son[0]==x) w=1;    else w=0;    r=s[x].son[w];R=y;    s[R].son[1-w]=r;    if (r!=0) s[r].fa=R;    r=x;R=z;    if (!Is_root(y))    {        if (s[R].son[0]==y) s[R].son[0]=r;        else s[R].son[1]=r;    }    if (r!=0) s[r].fa=R;    r=y;R=x;    s[R].son[w]=r;    if (r!=0) s[r].fa=R;    update(y);update(x);}stack<int> S;void Preserve (int x){    while (!Is_root(x)) S.push(x),x=s[x].fa;S.push(x);    while (!S.empty()) Push_down(S.top()),S.pop();}void Splay (int x){    Preserve(x);    while (!Is_root(x))    {        int y=s[x].fa,z=s[y].fa;        if (!Is_root(y))        {            if ((s[y].son[1]==x)==(s[z].son[1]==y)) rotate(y);            else rotate(x);        }        rotate(x);    }}void Access (int x){    int last=0;    while (x!=0)    {        Splay(x);        s[x].son[1]=last;        update(x);/****/        last=x;        x=s[x].fa;    }}void Make_root (int x){    Access(x);    Splay(x);    s[x].rev^=1;}void Link (int x,int y){    Make_root(y);    s[y].fa=x;}void Split (int x,int y){    Make_root(x);    /*for (int u=1;u<=3;u++)        printf("%d %d %d %d\n",u,s[u].son[0],s[u].son[1],s[u].fa);        printf("\n");*/    Access(y);    /*for (int u=1;u<=3;u++)        printf("%d %d %d %d\n",u,s[u].son[0],s[u].son[1],s[u].fa);*/    Splay(y);}void Cut (int x,int y){    Split(x,y);    s[x].fa=0;    s[y].son[0]=0;    update(y);}int main(){    scanf("%d%d",&n,&q);    for (int u=1;u<=n;u++)  s[u].bt();    for (int u=1;u<n;u++)    {        int x,y;        scanf("%d%d",&x,&y);        Link(x,y);    }    while (q--)    {        char ss[5];        scanf("%s",ss);        if (ss[0]=='+')//都加上这个数        {            int x,y,c;            scanf("%d%d%d",&x,&y,&c);            Split(x,y);cal(y,1,c);          }        else if (ss[0]=='-')        {            int x1,y1;            scanf("%d%d",&x1,&y1);            Cut(x1,y1);            scanf("%d%d",&x1,&y1);            Link(x1,y1);        }        else if (ss[0]=='*')        {            int x,y,c;            scanf("%d%d%d",&x,&y,&c);            Split(x,y);cal(y,c,0);            //printf("%d %d %d %d\n",x,y,s[x].d,s[x].c);        }        else        {            int x,y;            scanf("%d%d",&x,&y);            Split(x,y);            //update(x);update(y);            //printf("%d %d %d\n",x,s[x].son[0],s[x].son[1]);            //printf("%d %d %d %d %d %d\n",x,s[x].c,y,s[y].c,s[y].son[0],s[y].son[1]);            printf("%d\n",s[y].c);        }    }    return 0;}
原创粉丝点击