zoukankan      html  css  js  c++  java
  • [UOJ#207. 共价大爷游长沙]——LCT&随机化

    题目大意:

      传送门

      给一颗动态树,给出一些路径并动态修改,每次询问一条边是否被所有路径覆盖。

    题解:

      先%一发myy。

      开始感觉不是很可做的样子,发现子树信息无论维护什么都不太对……

      然后打开题目标签……随机化……

      emmmm,突然想到[bzoj 3569]DZY loves Chinese II……

      随机大法好…

      给每条路径随机一个权值,然后用异或来统计子树权值和,并与全集的异或和做下比较,然后就是LCT大板子……

      板子写挂……wa了两遍……迷。

    代码:

      1 #include "bits/stdc++.h"
      2 
      3 inline int read(){
      4     int s=0,k=1;char ch=getchar();
      5     while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
      6     while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
      7     return s*k;
      8 }
      9 
     10 using namespace std;
     11 
     12 const int N=2e5+10;
     13 
     14 namespace LCT{
     15     #define rev(t) (t?t->rev^=1:0)
     16     #define is_root(t) (!t->fa||(t->fa->son[0]!=t&&t->fa->son[1]!=t))
     17     #define son(t) (t->fa->son[1]==t)
     18     #define size(t) (t?t->size:0)
     19     struct node{
     20         node *fa,*son[2];
     21         int rev,size,empty;
     22         node () {fa=son[0]=son[1]=NULL,empty=rev=size=0;}
     23         inline void update(){
     24             size=size(son[0])^size(son[1])^empty;
     25         }
     26         inline void pushdown(){
     27             if (!rev) return ;
     28             rev(son[0]),rev(son[1]);
     29             swap(son[0],son[1]);rev=0;
     30         }
     31     }tree[N/2],*tmp[N/2];
     32     
     33     inline void rotate(node *p){
     34         int a=son(p)^1;node *f=p->fa;
     35         f->son[a^1]=p->son[a];
     36         if (p->son[a]) p->son[a]->fa=f;
     37         p->fa=f->fa;
     38         if (!is_root(f)) f->fa->son[son(f)]=p;
     39         f->fa=p,p->son[a]=f,f->update(),p->update();
     40     }
     41     
     42     inline void update(node *p){
     43         if (!is_root(p)) update(p->fa);
     44         p->pushdown();
     45     }
     46     
     47     inline void splay(node *p){
     48         register int pos=0;
     49         for(node *t=p;;t=t->fa){
     50             tmp[++pos]=t;
     51             if(is_root(t)) break;
     52         }
     53         for(;pos;--pos) tmp[pos]->pushdown();
     54         for(;!is_root(p);rotate(p))
     55             if(!is_root(p->fa)) rotate(son(p)==son(p->fa)?p->fa:p);
     56     }
     57     
     58     inline void access(node *p){
     59         for(node *pre=NULL;p;pre=p,p=p->fa)
     60             splay(p),p->empty^=size(p->son[1])^size(pre),p->son[1]=pre,p->update();
     61     }
     62     
     63     inline void make_root(node *x) {
     64         access(x),splay(x),x->rev^=1;
     65     }
     66     
     67     inline void link(node *x,node *y) {
     68         make_root(x);access(y),splay(y),x->fa=y;
     69         y->empty^=size(x),y->update();
     70     }
     71     
     72     inline void cut(node *x,node *y){
     73         make_root(x),access(y),splay(y);
     74         x->fa=y->son[0]=NULL;y->update();
     75     }
     76     
     77     inline int query(node *x,node *y) {
     78         make_root(x);access(y),splay(y);
     79         return size(x);
     80     }
     81 }
     82 
     83 int n,m;
     84 int a[N],b[N],c[N],cnt,tot;
     85 
     86 int main (int argc, char const* argv[]){
     87     //freopen("207.in","r",stdin);
     88     read();
     89     srand(201228);
     90     n=read(),m=read();
     91     register int i;
     92     using namespace LCT;
     93     for (i=1;i<n;++i) {
     94         int x=read(),y=read();
     95         link(tree+x,tree+y);
     96     }
     97     int type,x,y,u,v;
     98     while (m--) {
     99         type=read();
    100         switch (type) {
    101             case 1: x=read(),y=read(),u=read(),v=read(),cut(tree+x,tree+y),link(tree+u,tree+v);
    102             break;
    103             case 2: x=read(),y=read(),u=rand();
    104                     make_root(&tree[x]),tree[x].empty^=u,tree[x].update(),
    105                     make_root(&tree[y]),tree[y].empty^=u,tree[y].update();
    106                     ++cnt,a[cnt]=x,b[cnt]=y,c[cnt]=u,tot^=u;
    107             break;
    108             case 3: x=read();u=c[x],y=b[x],x=a[x];
    109                     make_root(&tree[x]),tree[x].empty^=u,tree[x].update(),
    110                     make_root(&tree[y]),tree[y].empty^=u,tree[y].update();
    111                     tot^=u;
    112             break;
    113             case 4: x=read(),y=read();
    114                     printf("%s
    ",tot==query(tree+x,tree+y)?"YES":"NO");
    115             break;
    116         }
    117     }
    118 }
  • 相关阅读:
    大话串口:我和它的恩恩怨怨
    分布式网游server的一些想法(一) 语言和平台的选择
    C++: C没有闭包真的很痛苦……
    C++不是C/C++
    最美树算法
    类魔兽世界 技能 天赋 成就 log 系统设计
    C++网游服务端开发(一):又无奈的重复造了个轮子,一个底层网络库
    C++ protobuf 不仅仅是序列化……
    深入WPFStyle
    Illusion = Caliburn.Micro + MEF
  • 原文地址:https://www.cnblogs.com/Troywar/p/8981465.html
Copyright © 2011-2022 走看看