zoukankan      html  css  js  c++  java
  • [bzoj3786] 星系探索

      splay&&树的dfs序。。。这姿势太神了。

      膜了半天题解。http://blog.csdn.net/PoPoQQQ/article/details/41649197

      其实写那么久主要还是因为。。我的splay模版是含有size域的那种。。。在这题就用不了了TAT(或者说加了也没什么用。。)

      改姿势感觉好蛋疼。。

      比较奇怪的是我改成递归建树后只快了不到1s= =。。时限40s我跑了39+s。。

      很好奇别人2K+代码是怎么写的= =

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #define ll long long
      5 using namespace std;
      6 const int maxn=100233;
      7 struct zs{int too,pre;}e[maxn];
      8 int tot,last[maxn];
      9 int l[maxn],r[maxn],tim;
     10 int ch[maxn<<1][2],numl[maxn<<1],numr[maxn<<1],fa[maxn<<1],v[maxn<<1],cnt;
     11 ll sum[maxn<<1],add[maxn<<1];
     12 int st[maxn<<1],top;
     13 int gg[maxn<<1],val[maxn];
     14 int i,j,k,n,m,x,y,rt;
     15 int ra,fh;char rx,id;
     16 inline int read(){
     17     rx=getchar(),ra=0,fh=1;
     18     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
     19     if(rx=='-')fh=-1,rx=getchar();
     20     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
     21 }
     22 inline void _add(int x,int q){
     23     if(gg[x]==1)v[x]+=q;else if(gg[x]==2)v[x]-=q;
     24     sum[x]+=(ll)(numl[x]-numr[x])*q,
     25     add[x]+=q;
     26 }
     27 inline void upd(int x){
     28     int l=ch[x][0],r=ch[x][1];
     29     sum[x]=sum[l]+sum[r]+v[x],
     30     numl[x]=numl[l]+numl[r]+(gg[x]==1),
     31     numr[x]=numr[l]+numr[r]+(gg[x]==2);
     32 }
     33 inline void pushdown(int x){
     34     if(!add[x])return;
     35     if(ch[x][0])_add(ch[x][0],add[x]);
     36     if(ch[x][1])_add(ch[x][1],add[x]);
     37     add[x]=0;
     38 }
     39 inline void rotate(int x){
     40     int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1;
     41     if(f!=rt)ch[gfa][ch[gfa][1]==f]=x;else rt=x;
     42     fa[fa[fa[ch[f][l]=ch[x][r]]=ch[x][r]=f]=x]=gfa,upd(f);
     43 }
     44 inline void splay(int &rt,int x){
     45     int f,gfa;
     46     for(st[top=1]=f=x;fa[f];st[++top]=(f=fa[f]));
     47     while(top)pushdown(st[top--]);
     48     while(x!=rt){
     49         f=fa[x],gfa=fa[f];
     50         if(f!=rt)
     51             rotate((ch[f][1]==x)!=(ch[gfa][1]==f)?x:f);
     52         rotate(x);
     53     }
     54     upd(x);
     55 }
     56 inline int getmn(int x){while(ch[x][0])x=ch[x][0];return x;}
     57 inline int getmx(int x){while(ch[x][1])x=ch[x][1];return x;}
     58 inline int split(int x,int y){
     59     int a,b;
     60     splay(rt,x),a=getmx(ch[x][0]);
     61     splay(rt,y),b=getmn(ch[y][1]);
     62     splay(rt,a),splay(ch[a][1],b);
     63     return ch[b][0];
     64 }
     65 inline void move(int a,int b){
     66     int x,y,z=split(l[a],r[a]);
     67     x=rt,y=ch[x][1],
     68     ch[y][0]=0,upd(y),upd(x);
     69     x=l[b],splay(rt,x),y=getmn(ch[x][1]),
     70     splay(ch[x][1],y),ch[y][0]=z,fa[z]=y,upd(y),upd(x);
     71 }
     72 inline ll query(int a){x=split(l[1],l[a]);return sum[x];}
     73 inline void change(int p,int q){int x=split(l[p],r[p]);_add(x,q);}
     74 inline void insert(int a,int b){e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;}
     75 inline void dfs(int x){
     76     l[x]=++tim;gg[tim]=1,v[tim]=val[x];
     77     for(int i=last[x];i;i=e[i].pre)dfs(e[i].too);
     78     r[x]=++tim;gg[tim]=2,v[tim]=-val[x];
     79 }
     80 inline void build(int a,int b,int pre){
     81     if(a>b)return;
     82     int mid=(a+b)>>1;
     83     if(pre)ch[pre][mid>pre]=mid;
     84     fa[mid]=pre,
     85     build(a,mid-1,mid),build(mid+1,b,mid);
     86     upd(mid);
     87 }
     88 int main(){
     89     tim=1;rt=1;gg[rt]=3;upd(rt);
     90     n=read();
     91     for(i=2;i<=n;i++)insert(read(),i);
     92     for(i=1;i<=n;i++)val[i]=read();
     93     dfs(1);
     94     tim++;gg[tim]=3;
     95     build(1,tim,0);rt=(1+tim)>>1;
     96     for(m=read();m;m--){
     97         for(id=getchar();id<'A'||id>'Z';id=getchar());
     98         x=read();if(id!='Q')y=read();
     99         if(id=='Q')printf("%lld
    ",query(x));
    100         if(id=='F')change(x,y);
    101         if(id=='C')move(x,y);
    102     }
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    Linux:DHCP服务配置
    调整 全局jvm 大小 tomcat 调整jvm大小
    Arts打卡第8周
    mysql 对返回的值是null进行判断和重新赋值
    从xml中返回的对象,和new 返回的对象时不同的。
    检查时异常和运行是异常 + 事务回滚 +隔离级别
    怎么在for循环中新建出不同的list
    mysql中查询某个字段重复的数据
    Arts打卡第7周
    将Excel文件导入到Navicat Premium中日期变为0000-00-00
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5317199.html
Copyright © 2011-2022 走看看