• 【BZOJ3282】Tree LCT


    1A爽,感觉又对指针重怀信心了呢= =,模板题,注意单点修改时splay就好,其实按吾本意是没写的也A了,不过应该加上能更好维护平衡性。

    。。还是得加上好= =

      1 #include <iostream>
      2 #include <cstdio>
      3 #define N 300010
      4 using namespace std;
      5 int n,m;
      6 struct node
      7 {
      8     node *fa,*ch[2];
      9     int xor_sum,data;
     10     bool rev;
     11     node(int x);
     12     bool chr() {return this==fa->ch[1];}
     13     bool isrt() {return this!=fa->ch[1] && this!=fa->ch[0];}
     14     void setc(node *x,int t) {this->ch[t]=x; x->fa=this;}
     15     void push_up()    {xor_sum=ch[0]->xor_sum^ch[1]->xor_sum^data;}
     16     void push_down() 
     17     {
     18         if (!isrt()) fa->push_down();
     19         if (rev)
     20         {
     21             ch[1]->rev^=1;
     22             ch[0]->rev^=1;
     23             swap(ch[0],ch[1]);
     24             rev=0;
     25         } 
     26     }
     27 }*null=new node(0),*lct[N];
     28 node::node(int x)
     29 {
     30     fa=ch[1]=ch[0]=null;
     31     data=xor_sum=x;
     32     rev=0;
     33 }
     34 inline int read()
     35 {
     36     int ans=0,f=1;
     37     char c;
     38     while (!isdigit(c=getchar())){if (c=='-') f=-1;}
     39     ans=c-'0';
     40     while (isdigit(c=getchar())) ans=ans*10+c-'0';
     41     return ans*f;
     42 }
     43 namespace LCT
     44 {
     45     void rotate(node *x)
     46     {
     47         node *r=x->fa;
     48         int t=x->chr();
     49         if (x==null || r==null) return;
     50         //x->push(); y->push();
     51         if (r->isrt()) x->fa=r->fa;
     52         else r->fa->setc(x,r->chr());
     53         r->setc(x->ch[t^1],t);
     54         x->setc(r,!t);
     55         x->push_up(); r->push_up();
     56     }
     57     void splay(node *x)
     58     {
     59         x->push_down();
     60         for (;!x->isrt();rotate(x))
     61             if (!x->fa->isrt())
     62                 if (x->chr()==x->fa->chr()) rotate(x->fa);
     63                 else rotate(x);
     64         x->push_up();
     65     }
     66     void Access(node *x)
     67     {
     68         node *y=null;
     69         for (;x!=null;y=x,x=x->fa)
     70         {
     71             splay(x);
     72             x->ch[1]=y;
     73         }
     74     }
     75     void MakeRoot(node *x)
     76     {
     77         Access(x); splay(x); x->rev^=1;
     78     }
     79     void Link(node *x,node *y)
     80     {
     81         MakeRoot(x); //Access(y); splay(y);
     82         x->fa=y;
     83     }
     84     void Cut(node *x,node *y)
     85     {
     86         MakeRoot(x); Access(y); splay(y);
     87         y->ch[0]->fa=null; y->ch[0]=null;
     88     }
     89     node *Findfa(node *x)
     90     {
     91         Access(x); splay(x);
     92         while (x->ch[0]!=null) x=x->ch[0];
     93         return x;
     94     }
     95     void Change(node *x,int v)
     96     {
     97         x->push_down();
     98         splay(x);
     99         x->data=v;
    100         x->push_up();
    101     }
    102     int Query(node *x,node *y)
    103     {
    104         MakeRoot(x);
    105         Access(y);
    106         splay(y);
    107         return y->xor_sum;
    108     }
    109 }
    110 using namespace LCT;
    111 int main()
    112 {
    113     int temp,x,y;
    114     n=read();
    115     m=read();
    116     for (int i=1;i<=n;i++) x=read(),lct[i]=new node(x);
    117     for (int i=1;i<=m;i++)
    118     {
    119         temp=read(); x=read(); y=read();
    120         switch (temp)
    121         {
    122             case 0:printf("%d
    ",LCT::Query(lct[x],lct[y])); break;
    123             case 1:if (Findfa(lct[x])!=Findfa(lct[y])) Link(lct[x],lct[y]); break;
    124             case 2:if (Findfa(lct[x])==Findfa(lct[y])) Cut(lct[x],lct[y]); break; 
    125             case 3:Change(lct[x],y); break;
    126         }
    127     }
    128     return 0;
    129 }
    View Code

    Description

    给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。

    0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。

    1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。

    2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。

    3:后接两个整数(x,y),代表将点X上的权值变成Y。

     

    Input

    第1行两个整数,分别为N和M,代表点数和操作数。

    第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。

    第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。

     

     

     

     

    Output

    对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。

    Sample Input

    3 3
    1
    2
    3
    1 1 2
    0 1 2
    0 1 1

    Sample Output

    3
    1

    HINT

    1<=N,M<=300000

    Source

    —Anime Otaku Save The World.
  • 相关阅读:
    一个误解: 单个服务器程序可承受最大连接数“理论”上是“65535”
    Memcached 命令简介
    MySQL性能测试
    WCF 面向服务的SOAP消息
    WCF SOAP消息剖析
    深入探析 socket
    C#设计模式(适配器模式)
    LoadRunner中的异常处理
    反射调用性能比较(附源码)
    避免 TCP/IP 端口耗尽
  • 原文地址:https://www.cnblogs.com/DMoon/p/5325849.html
Copyright © 2020-2023  润新知