zoukankan      html  css  js  c++  java
  • bzoj 2759一个动态树好题

    真的是动态树好题,如果把每个点的父亲设成p[x],那么建出来图应该是一个环套树森林,拆掉一条边,就变成了动态树,考虑维护什么,对于LCT上每个节点,维护两组k和b,一组是他到他父亲的,一组是他LCT子树中深度最深的点到深度最浅的点的父亲的k和b,查询时只需查询一颗树中sf到自己的k和b,判断是否有唯一解,然后再解就可以了。注意不能换根,因为树的形态是固定的。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define N 30005
      7 #define mod 10007
      8 using namespace std;
      9 int n,p[N],q;
     10 int qp(int a,int b){
     11     int c=1;
     12     while(b){
     13         if(b&1)c=c*a%mod;
     14         a=a*a%mod;b>>=1;
     15     }
     16     return c;
     17 }
     18 struct Node{
     19     Node *ch[2],*fa,*sf;
     20     int k,b,sumk,sumb,id;
     21     Node();
     22     void pushup();
     23     void pushdown();
     24 }*null=new Node,tree[N];
     25 Node :: Node (){
     26     ch[0]=ch[1]=fa=sf=null;
     27     k=sumk=1;b=sumb=id=0;
     28 }
     29 void Node :: pushup(){
     30     sumk=k;sumb=b;
     31     sumb=(sumk*ch[0]->sumb%mod+sumb)%mod;sumk=ch[0]->sumk*sumk%mod;
     32     sumb=(ch[1]->sumk*sumb%mod+ch[1]->sumb)%mod;sumk=sumk*ch[1]->sumk%mod;
     33 }
     34 void rotate(Node *x){
     35     Node *y=x->fa,*z=y->fa;
     36     int w=y->ch[0]==x;
     37     x->ch[w]->fa=y;y->ch[w^1]=x->ch[w];
     38     y->fa=x;x->ch[w]=y;
     39     if(z->ch[0]==y)z->ch[0]=x;
     40     if(z->ch[1]==y)z->ch[1]=x;
     41     x->fa=z;
     42     y->pushup();x->pushup();
     43 }
     44 bool isroot(Node *x){
     45     return x->fa->ch[0]!=x && x->fa->ch[1]!=x;
     46 }
     47 void splay(Node *x){
     48     Node *y,*z;
     49     while(!isroot(x)){
     50         y=x->fa;z=y->fa;
     51         if((z->ch[0]==y&&y->ch[0]==x)||(z->ch[1]==y&&y->ch[1]==x))
     52             rotate(y);
     53         rotate(x);
     54     }
     55 }
     56 void access(Node *x){
     57     Node *y=null;
     58     while(x!=null){
     59         splay(x);
     60         x->ch[1]=y;
     61         x->pushup();
     62         y=x;x=x->fa;
     63     }
     64 }
     65 Node * find(Node *x){
     66     access(x);splay(x);
     67     while(x->ch[0]!=null)x=x->ch[0];
     68     return x;
     69 }
     70 void cut(Node *x){
     71     Node *rt=find(x);
     72     if(rt==x)x->sf=null;
     73     else{
     74         access(x);
     75         splay(x);
     76         x->ch[0]->fa=null;
     77         x->ch[0]=null;
     78         x->pushup();
     79         if(find(rt->sf)!=find(rt)){
     80             rt->fa=rt->sf;
     81             rt->sf=null;
     82         }
     83     }
     84 }
     85 void link(Node *x,Node *f,int k,int b){
     86     x->k=k;x->b=b;
     87     if(find(f)==find(x))x->sf=f;
     88     else x->fa=f;
     89 }
     90 int query(Node *x){
     91     Node *rt=find(x),*now=rt->sf;
     92     access(now);splay(now);    
     93     if(now->sumk==1){
     94         if(now->sumb==0)return -2;
     95         else return -1;
     96     }
     97     int ans=(mod-now->sumb)*qp(((now->sumk-1)+mod)%mod,mod-2)%mod;
     98     access(x);splay(x);    
     99     return (ans*x->sumk%mod+x->sumb)%mod;
    100 }
    101 int main(){
    102     srand(20001101);
    103     null->fa=null->ch[0]=null->ch[1]=null->sf=null;
    104     scanf("%d",&n);
    105     for(int i=1,k,b;i<=n;i++){
    106         tree[i].id=i;
    107         scanf("%d%d%d",&k,&p[i],&b);
    108         link(&tree[i],&tree[p[i]],k,b);
    109     }   
    110     scanf("%d",&q);
    111     char ch[5];
    112     int x,y,z,w;
    113     while(q--){
    114         scanf("%s",ch);
    115         if(ch[0]=='A'){
    116             scanf("%d",&x);
    117             printf("%d
    ",query(&tree[x]));
    118         }
    119         else{
    120             scanf("%d%d%d%d",&x,&y,&z,&w);
    121             cut(&tree[x]);p[x]=z;
    122             link(&tree[x],&tree[p[x]],y,w);
    123         }
    124     }
    125     return 0;
    126 } 
    View Code
  • 相关阅读:
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实现
    C语言博客作业06--结构体&文件
    C语言博客05--指针
    DS博客作业07--查找
    DS博客作业06--图
    DS博客作业05--树
    DS博客作业03--栈和队列
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实验
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8213563.html
Copyright © 2011-2022 走看看