zoukankan      html  css  js  c++  java
  • BZOJ 3786 星系探索 (splay+dfs序)

    题目大意:给你一棵树,支持一下三种操作

    1.获取某节点到根节点的路径上所有节点的权值和

    2.更换某棵子树的父亲

    3.某子树内所有节点的权值都增加一个值w

    当时想到了splay维护dfs序,查完题解发现思路是对的,然后我就写了足足6个小时才A

    st[x]代表入栈时间,ed[x]代表出栈时间

    对于第一个操作,每个树上节点在splay中都有两个位置,分别对应入栈出栈序,然后把入栈的点权*1,出栈点权*-1,就可以避免其它子树干扰了

    接着查询到根节点的路径权值和呢,splay把1~st[x]整个序列都扔到一个子树里,求一下子树权值和即可

    第二个操作,可以找一下st[x]和ed[x]对应splay中节点的前驱和后继,把它们都搞到一个splay子树里,在把整棵树接到要求的父节点即可

    第三个操作,和第二个操作类似,找前驱后继然后在子树打标记即可,此外,还要维护splay子树内的入栈节点数-出栈节点数来直接得到splay子树的权值和。

    注意,一定要在所有能传标记的地方都传标记,不论是从下往上splay,还是从上到下找前驱or后继,而如果不在找前驱后继的过程中下传标记,上层的标记无法被传到下层,导致结果错误!就这个错误我调了2个小时!

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #define N 200100
      5 #define il inline
      6 #define ll long long 
      7 #define root d[0].ch[1]
      8 using namespace std;
      9 
     10 char q[10];
     11 int n,m,cte,tot;
     12 int st[N],ed[N],head[N],sq[N];
     13 ll w[N];
     14 struct EDGE{int to,nxt;}edge[N];
     15 struct SPLAY{int fa,ch[2],ss,fl;ll val,sum,tag;}d[N];
     16 il int idf(int x){return d[d[x].fa].ch[0]==x?0:1;}
     17 il void con(int x,int ff,int p){d[ff].ch[p]=x;d[x].fa=ff;}
     18 il void pushup(int x){
     19     d[x].sum=d[d[x].ch[0]].sum+d[d[x].ch[1]].sum+d[x].val;
     20     d[x].ss=d[d[x].ch[0]].ss+d[d[x].ch[1]].ss+d[x].fl;
     21 }
     22 il void pushdown(int x){
     23     if(!d[x].tag) return;
     24     int ls=d[x].ch[0],rs=d[x].ch[1];
     25     d[ls].tag+=d[x].tag,d[rs].tag+=d[x].tag;
     26     d[ls].val+=d[x].tag*(ll)d[ls].fl,d[rs].val+=d[x].tag*(ll)d[rs].fl;
     27     d[ls].sum+=d[x].tag*(ll)d[ls].ss,d[rs].sum+=d[x].tag*(ll)d[rs].ss;
     28     d[x].tag=0;
     29 }
     30 il void rot(int x){
     31     int y=d[x].fa;int ff=d[y].fa;int px=idf(x);int py=idf(y);
     32     pushdown(y),pushdown(x);
     33     con(d[x].ch[px^1],y,px),con(y,x,px^1),con(x,ff,py);
     34     pushup(y),pushup(x);
     35 }
     36 il void splay(int x,int to){
     37     to=d[to].fa;
     38     while(d[x].fa!=to){
     39         int y=d[x].fa;
     40         if(d[y].fa==to) rot(x);
     41         else if(idf(x)==idf(y)) rot(y),rot(x);
     42         else rot(x),rot(x);}
     43 }
     44 int gc(){
     45     int rett=0,fh=1;char p=getchar();
     46     while(p<'0'||p>'9'){if(p=='-')fh=-1;p=getchar();}
     47     while(p>='0'&&p<='9'){rett=(rett<<3)+(rett<<1)+p-'0';p=getchar();}
     48     return rett*fh;
     49 }
     50 void ae(int u,int v){
     51     cte++;edge[cte].to=v;
     52     edge[cte].nxt=head[u];head[u]=cte;
     53 }
     54 void dfs1(int u,int ff)
     55 {
     56     st[u]=++tot,sq[tot]=u,d[tot].val=w[u],d[tot].fl=1;
     57     for(int j=head[u];j!=-1;j=edge[j].nxt){
     58         int v=edge[j].to;
     59         if(v==ff) continue;
     60         dfs1(v,u);}
     61     ed[u]=++tot,sq[tot]=u,d[tot].val=-w[u],d[tot].fl=-1;
     62 }
     63 int build(int l,int r)
     64 {
     65     if(l>r) return 0;
     66     int mid=(l+r)>>1;
     67     con(build(l,mid-1),mid,0);
     68     con(build(mid+1,r),mid,1);
     69     pushup(mid);
     70     return mid;
     71 }
     72 int lower(int x)
     73 {
     74     pushdown(x),x=d[x].ch[0];
     75     while(x){
     76         pushdown(x);
     77         if(d[x].ch[1]) x=d[x].ch[1];
     78         else break;}
     79     return x;
     80 }
     81 int upper(int x)
     82 {
     83     pushdown(x),x=d[x].ch[1];
     84     while(x){
     85         pushdown(x);
     86         if(d[x].ch[0]) x=d[x].ch[0];
     87         else break;}
     88     return x;
     89 }
     90 ll query(int x)
     91 {
     92     splay(st[0],root);
     93     splay(st[x],d[root].ch[1]);
     94     int lw=upper(st[x]);
     95     splay(lw,d[root].ch[1]);
     96     return d[d[lw].ch[0]].sum;
     97 }
     98 void add(int x,ll ww)
     99 {
    100     int trl,trr,rt;
    101     splay(st[x],root);
    102     splay(ed[x],d[root].ch[1]);
    103     trl=lower(st[x]);
    104     splay(trl,root);
    105     trr=upper(ed[x]);
    106     splay(trr,d[root].ch[1]);
    107     rt=d[trr].ch[0];
    108     d[rt].val+=ww*(ll)d[rt].fl;
    109     d[rt].sum+=ww*(ll)d[rt].ss;
    110     d[rt].tag+=ww;
    111 }
    112 void mov(int x,int y)
    113 {
    114     int trl,trr,frt,rtt;
    115     splay(st[x],root);
    116     splay(ed[x],d[root].ch[1]);
    117     trl=lower(st[x]);
    118     splay(trl,root);
    119     trr=upper(ed[x]);
    120     splay(trr,d[root].ch[1]);
    121     pushdown(trl),pushdown(trr);
    122     rtt=d[trr].ch[0];
    123     d[trr].ch[0]=0,d[rtt].fa=0;
    124     pushup(trr),pushup(trl);
    125     
    126     splay(st[y],root);
    127     splay(ed[y],d[root].ch[1]);
    128     trl=lower(ed[y]);
    129     if(trl) con(rtt,trl,1);
    130     else con(rtt,ed[y],0);
    131     splay(rtt,root);
    132 }
    133 void print(int x)
    134 {
    135     if(d[x].ch[0]) print(d[x].ch[0]);
    136     printf("%d ",sq[x]);
    137     if(d[x].ch[1]) print(d[x].ch[1]);
    138 }
    139 
    140 int main()
    141 {
    142     scanf("%d",&n);
    143     int x,y;
    144     memset(head,-1,sizeof(head));
    145     for(int i=2;i<=n;i++)
    146         x=gc(),ae(x,i),ae(i,x);
    147     for(int i=1;i<=n;i++)
    148         w[i]=gc();
    149     st[0]=++tot,dfs1(1,-1),ed[0]=++tot;
    150     root=build(1,tot);
    151     scanf("%d",&m);
    152     for(int i=1;i<=m;i++){
    153         scanf("%s",q);
    154         if(q[0]=='Q'){
    155             x=gc();
    156             printf("%lld
    ",query(x));
    157         }else if(q[0]=='F'){
    158             x=gc(),y=gc();
    159             add(x,(ll)y);
    160         }else{
    161             x=gc(),y=gc();
    162             mov(x,y);
    163         }
    164     }
    165     /*for(int i=1;i<=n;i++)
    166         printf("%lld %lld %lld
    ",query(i),d[st[i]].val,d[ed[i]].val);*/
    167     return 0;
    168 }
  • 相关阅读:
    Qt ------ QPainter 和控件组件的重绘
    Qt error ------ no matching function for call to QObject::connect(QSpinBox*&, <unresolved overloaded function type>, QSlider*&, void (QAbstractSlider::*)(int))
    DHCP 服务器功能
    matlab --- plot画图
    网站跨域解决方案有哪些
    分布式Session一致性解决方案有哪些?
    博客收集
    idea快捷键
    Linux打包、压缩与解压详解
    lastIndex()与IndexOf()的区别
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9697056.html
Copyright © 2011-2022 走看看