【BZOJ2814】tree

来源:互联网 发布:乌柏林根空难 知乎 编辑:程序博客网 时间:2024/06/05 11:02

Description

给出一棵N 个点的树,每个点有两层,每层有权值和颜色(黑白) 。要求支持以下操作。
1. Cover s t color 将s到t的路径上的点的两层的颜色全部置为 color(0 白1 黑)
2. CVal index layer val 将index号点的 layer 层的权值修改为 val
3. CColor index layer color 将 index号点的 layer 层的颜色修改为 color
4. QMax s t 询问s到 t的路径上的白色最大权值和路径的权值(任意白色层为起点,每次只能往相同点不同层或者相邻点同一层上移动,每个点的每一层最多走一次,路径经过的层必须都是白色) ,若 s到 t上的路径没有白点则输出[Bad Request.]
5. QLen s t 询问s到t的路径上的白色最大权值和路径的长度,若 s到 t的路径上没有白点则输出 0
初始树上权值均为 1,颜色均为白色。
N<=5W,Q<=5W,1<=val<=1K,0<=color,layer<=1 所有数据不超过longint范围。 .
对于40%的分数,没有 1,5 号操作,N,Q <= 1K
对于80%的分数,没有 5号操作
Input

第一行一个数 N,接下来N*2-2 个数 s,t,代表 s与t之间有连边。第N+1行一个数 Q,
表示操作数。接下来Q 行每行一个操作。
Output

对于每次 QMax,QLen输出对应答案,用换行符分隔。
Sample Input

6

1 2 2 4 2 5 1 3 3 6

7

CVal 1 0 5

CVal 1 1 3

CColor 1 0 1

CVal 2 0 5

CVal 3 0 3

QMax 5 6

QLen 5 6

Sample Output

17

9
HINT

Source

人生成就,写过最长的码农题
半天写代码,半天调代码
LCT大法好啊,比链剖看着美观多了QwQ

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 50010#define GET (ch >= '0' && ch <= '9')#define MAXINT 0x3f3f3f3fusing namespace std;int n,m;int sta[MAXN],top;char ch[8];inline void in(int &x){    char ch = getchar() ; x = 0;    while (!GET)    ch = getchar();    while (GET) x = x * 10 + ch - '0' , ch = getchar();}//节点颜色 1为白色 0为黑色 //Data Transmit inline void update(int &a,int &b,int c,int d){    if (a < c)  a = c , b = d;    else    if (a == c && b < d)    b = d;}//Define Information Node struct treenode{    int len1[2][2],len2[2][2];      int val1[2][2],val2[2][2];    int llen[2],rlen[2];    int lval[2],rval[2];    int minn[2][2];      int size,sum;    int maxl,maxv;    treenode()    {        for (int i = 0 ; i <= 1 ; i++)  lval[i] = rval[i] = llen[i] = rlen[i] = -MAXINT;        maxl = maxv = -MAXINT , size = sum = 0;        for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)            len1[i][j] = len2[i][j] = val1[i][j] = val2[i][j] = -MAXINT,            minn[i][j] = MAXINT;    }    //Node Union     inline friend treenode operator + (const treenode& a,const treenode& b)    {        treenode ret;        for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)  //floyed         {            for (int k = 0 ; k <= 1 ; k++)                update(ret.val1[i][j] , ret.len1[i][j] , a.val1[i][k] + b.val1[k][j] , a.len1[i][k] + b.len1[k][j]),                update(ret.val2[i][j] , ret.len2[i][j] , a.val2[i][k] + b.val2[k][j] , a.len2[i][k]+b.len2[k][j]),                update(ret.lval[i] , ret.llen[i] , a.val1[i][k] + b.lval[k] , a.len1[i][k] + b.llen[k]),                update(ret.rval[j] , ret.rlen[j] , a.rval[k] + b.val2[j][k] , a.rlen[k] + b.len2[k][j]),                ret.minn[i][j] = min(ret.minn[i][j] , min(a.minn[i][k] , b.minn[k][j]));            update(ret.lval[i] , ret.llen[i] , a.lval[i] , a.llen[i]);            update(ret.rval[j] , ret.rlen[j] , b.rval[j] , b.rlen[j]);        }        update(ret.maxv , ret.maxl , a.maxv , a.maxl);        update(ret.maxv , ret.maxl , b.maxv , b.maxl);        for (int i = 0 ; i <= 1 ; i++)  update(ret.maxv , ret.maxl , a.rval[i] + b.lval[i] , a.rlen[i] + b.llen[i]);        ret.size = a.size + b.size ; ret.sum = a.sum + b.sum;        return ret;    }};//Define LCT struct splay{    int ch[2],fa,val[2];    bool flag,cov,col[2];    treenode w;}tree[MAXN];//Get Node inline treenode findnode(int x){    treenode ret ; ret.size = 2 ; ret.sum = tree[x].val[0] + tree[x].val[1];    for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)      {        ret.minn[i][j] = min(tree[x].val[i] , tree[x].val[j]);        if (tree[x].col[i] && tree[x].col[j])        {            ret.len1[i][j] = ret.len2[i][j] = (i == j ? 1 : 2),            ret.val1[i][j] = ret.val2[i][j] = (i == j ? tree[x].val[i] : tree[x].val[i] + tree[x].val[j]);            update(ret.maxv , ret.maxl , ret.val1[i][j] , ret.len1[i][j]),            update(ret.lval[i] , ret.llen[i] , ret.val1[i][j] , ret.len1[i][j]),            update(ret.rval[j] , ret.rlen[j] , ret.val2[i][j] , ret.len2[i][j]);        }    }    return ret;}//Information Update inline void push_up(int x){    if (!x) return;    tree[x].w = findnode(x);    if (tree[x].ch[0])  tree[x].w = tree[tree[x].ch[0]].w + tree[x].w;    if (tree[x].ch[1])  tree[x].w = tree[x].w + tree[tree[x].ch[1]].w;}inline void Cover(int x,bool col){    treenode ret;    tree[x].flag = 1 , tree[x].cov = col;    tree[x].col[0] = tree[x].col[1] = col;    if (col)    {        if ((tree[x].w.size >> 1) & 1)        {            for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)                if (i != j)                    ret.len1[i][j] = ret.len2[i][j] = tree[x].w.size,                    ret.val1[i][j] = ret.val2[i][j] = tree[x].w.sum;                else                    ret.len1[i][j] = ret.len2[i][j] = tree[x].w.size - 1,                    ret.val1[i][j] = ret.val2[i][j] = tree[x].w.sum - tree[x].w.minn[i][j];        }        else        {            for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)                if (i == j)                    ret.len1[i][j] = ret.len2[i][j] = tree[x].w.size,                    ret.val1[i][j] = ret.val2[i][j] = tree[x].w.sum;                else                    ret.len1[i][j] = ret.len2[i][j] = tree[x].w.size - 1,                    ret.val1[i][j] = ret.val2[i][j] = tree[x].w.sum - tree[x].w.minn[i][j];        }        ret.maxl = tree[x].w.size ; ret.maxv = tree[x].w.sum;        for (int i = 0 ; i <= 1 ;i++)            ret.llen[i] = ret.rlen[i] = tree[x].w.size,            ret.lval[i] = ret.rval[i] = tree[x].w.sum;    }    ret.size = tree[x].w.size ; ret.sum = tree[x].w.sum;    for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)  ret.minn[i][j] = tree[x].w.minn[i][j];    tree[x].w = ret;}inline void push_down(int x){    if (!x) return;    if (tree[x].flag)    {        if (tree[x].ch[0])  Cover(tree[x].ch[0] , tree[x].cov);        if (tree[x].ch[1])  Cover(tree[x].ch[1] , tree[x].cov);        tree[x].flag = 0 ; tree[x].cov = 0;    }}//LCT Operation inline bool is_root(int x)  {   return tree[tree[x].fa].ch[0] != x && tree[tree[x].fa].ch[1] != x;  }inline void rot(int x){    int y = tree[x].fa,z = tree[y].fa,l,r;    l = (tree[y].ch[1] == x) ; r = l ^ 1;    if (!is_root(y))    tree[z].ch[tree[z].ch[1] == y] = x;    tree[x].fa = z;tree[y].fa = x ; tree[tree[x].ch[r]].fa = y;    tree[y].ch[l] = tree[x].ch[r] ; tree[x].ch[r] = y;    push_up(y) ; push_up(x);}inline void Splay(int x){    sta[++top] = x;    for (int i = x ; !is_root(i) ; i = tree[i].fa)  sta[++top] = tree[i].fa;    while (top) push_down(sta[top--]);    while (!is_root(x))    {        int y = tree[x].fa , z = tree[y].fa;        if (!is_root(y))        {            if ((tree[z].ch[0] == y) ^ (tree[y].ch[0] == x))    rot(x);            else    rot(y);        }        rot(x);    }}inline void access(int x)   {   for (int i = 0 ; x ; i = x , x = tree[x].fa)    Splay(x) , tree[x].ch[1] = i , push_up(x);  }//Paint Color (Operation No.1)inline void Set_color(int s,int t,bool col){    access(s);    for (int x = t , i = 0 ; x ; i = x , x = tree[x].fa)    {        Splay(x);        if (!tree[x].fa)        {            tree[x].col[0] = tree[x].col[1] = col;            if (tree[x].ch[1])  Cover(tree[x].ch[1] , col);            if (i)  Cover(i , col);        }        tree[x].ch[1] = i ; push_up(x);    }}//Node Modify (Operation No.2/3)  inline void modify_val(int x,int y,int z)   {   Splay(x) ; tree[x].val[y] = z ; push_up(x); }inline void modify_col(int x,int y,bool z)  {   Splay(x) ; tree[x].col[y] = z ; push_up(x); }//Query (Operation 4/5) inline treenode query(int s,int t){    access(s);    for (int x = t , i = 0 ; x ; i = x , x = tree[x].fa)    {        Splay(x);        if (!tree[x].fa)        {            treenode ret = findnode(x);            if (tree[x].ch[1])            {                treenode tmp = tree[tree[x].ch[1]].w;                for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)                    swap(tmp.len1[i][j] , tmp.len2[i][j]),                    swap(tmp.val1[i][j] , tmp.val2[i][j]);                for (int i = 0 ; i <= 1 ; i++)  swap(tmp.llen[i] , tmp.rlen[i]) , swap(tmp.lval[i] , tmp.rval[i]);                ret = tmp + ret;            }            if (i)  ret = ret + tree[i].w;            return ret;        }        tree[x].ch[1] = i ; push_up(x);    }}//initialization  inline void init(){    for (int i = 1 ; i <= n ; i++)    {        for (int j = 0 ; j <= 1 ; j++)  tree[i].val[j] = tree[i].col[j] = 1;        tree[i].w = findnode(i);    }}//DFS build Tree int Top;struct edge{    int to;    edge *next;}e[MAXN<<1],*prev[MAXN];void insert(int u,int v)    {   e[++Top].to = v ; e[Top].next = prev[u] ; prev[u] = &e[Top];    }void dfs(int x,int f){    tree[x].fa = f;    for (edge *i = prev[x] ; i ; i = i->next)        if (i->to != f)         {            if (!tree[x].ch[1]) tree[x].ch[1] = i->to;            dfs(i->to , x);        }}//debugvoid printnode(treenode x){    for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)  printf("%d ",x.val1[i][j]);    for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)  printf("%d ",x.val2[i][j]);    printf("\n");    for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)  printf("%d ",x.len1[i][j]);    for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)  printf("%d ",x.len2[i][j]);    printf("\n");    for (int i = 0 ; i <= 1 ; i++)  printf("%d ",x.llen[i]);    for (int i = 0 ; i <= 1 ; i++)  printf("%d ",x.rlen[i]);    printf("\n");    for (int i = 0 ; i <= 1 ; i++)  printf("%d ",x.lval[i]);    for (int i = 0 ; i <= 1 ; i++)  printf("%d ",x.rval[i]);    printf("\n");    for (int i = 0 ; i <= 1 ; i++)  for (int j = 0 ; j <= 1 ; j++)  printf("%d ",x.minn[i][j]);    printf("\n");    printf("%d %d %d %d\n",x.size , x.sum , x.maxl , x.maxv);}void print(int x){    printf("%d\n" , x);    printf("%d %d %d %d %d %d %d %d %d\n" , tree[x].ch[0] , tree[x].ch[1] , tree[x].fa , tree[x].val[0] , tree[x].val[1] , tree[x].flag , tree[x].cov , tree[x].col[0] , tree[x].col[1]);    printnode(tree[x].w);}int main(){    in(n) ; int u,v,w ; init() ;    for (int i = 1 ; i < n ; i++)   in(u) , in(v) , insert(u , v) , insert(v , u);    dfs(1 , 0);    for (int i = 1 ; i <= n ; i++)  if (!tree[i].ch[1]) Splay(i);    for (in(m) ; m ; m--)    {        scanf("%s",ch);        if (ch[1] == 'o')   in(u) , in(v) , in(w) , Set_color(u , v , w ^ 1);        if (ch[1] == 'V')   in(u) , in(v) , in(w) , modify_val(u , v , w);        if (ch[1] == 'C')   in(u) , in(v) , in(w) , modify_col(u , v , w ^ 1);        if (ch[1] == 'M')        {            in(u) , in(v) ; treenode ans = query(u , v);            if (ans.maxv < 0)   puts("Bad Request.");            else    printf("%d\n" , ans.maxv);        }        if (ch[1] == 'L')        {            in(u) , in(v) ; treenode ans = query(u , v);            printf("%d\n" , max(ans.maxl , 0));        }    }}
1 0
原创粉丝点击