• BZOJ2333:[SCOI2011]棘手的操作(Splay)


    Description

    N个节点,标号从1N,这N个节点一开始相互不连通。第i个节点的初始权值为a[i],接下来有如下一些操作:

    U x y: 加一条边,连接第x个节点和第y个节点

    A1 x v: 将第x个节点的权值增加v

    A2 x v: 将第x个节点所在的连通块的所有节点的权值都增加v

    A3 v: 将所有节点的权值都增加v

    F1 x: 输出第x个节点当前的权值

    F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值

    F3: 输出所有节点中,权值最大的节点的权值

    Input

    输入的第一行是一个整数N,代表节点个数。

    接下来一行输入N个整数,a[1], a[2], …, a[N],代表N个节点的初始权值。

    再下一行输入一个整数Q,代表接下来的操作数。

    最后输入Q行,每行的格式如题目描述所示。

    Output

    对于操作F1, F2, F3,输出对应的结果,每个结果占一行。

    Sample Input

    3
    0 0 0
    8
    A1 3 -20
    A1 2 20
    U 1 3
    A2 1 10
    F1 3
    F2 3
    A3 -10
    F3

    Sample Output

    -10
    10
    10

    HINT

    对于30%的数据,保证 N<=100,Q<=10000

    对于80%的数据,保证 N<=100000,Q<=100000

    对于100%的数据,保证 N<=300000,Q<=300000

    对于所有的数据,保证输入合法,并且 -1000<=v, a[1], a[2], …, a[N]<=1000

    Solution

    第一眼:这不splay启发式合并板子题吗?
    然后就开始漫长的写写写调调调
    维护多颗splay
    U:splay启发式合并,一个个删除小的splay插入到大的splay里面
    A1:删除val[x],插入val[x]+v
    A2:开个Add数组,维护每颗splay整体加的数
    A3:搞个全局变量ALL记一下就好了
    F1:直接输出val[x]+Add[x]+ALL
    F2:直接输出Max[ID[x]],其中ID是x所属的平衡树编号
    F3::这个相当于要维护Max[]的最大值。开个可删堆,每次Max[i]变化的时候就把旧的删掉,新的插入,F3查询的时候直接输出堆顶即可。
    emmm话说为什么大部分人都写的堆啊_(Xз」∠)_

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<queue>
      4 #define N (600000+1000) 
      5 using namespace std;
      6 
      7 int Son[N][2],Father[N],Size[N];
      8 int ID[N],Add[N],Val[N],Max[N];
      9 int Root[N],n,m,x,y,v,ALL;
     10 char opt[10];
     11 priority_queue<int>Heap,Del;
     12 
     13 int Get(int x){return Son[Father[x]][1]==x;}
     14 void Update(int x){Size[x]=Size[Son[x][0]]+Size[Son[x][1]]+1;}
     15 void Clear(int x){Son[x][0]=Son[x][1]=Father[x]=Size[x]=Val[x]=0;}
     16 
     17 int Pre(int x)
     18 {
     19     x=Son[x][0];
     20     while (Son[x][1]) x=Son[x][1]; 
     21     return x;
     22 }
     23 
     24 int Get_Max(int x)
     25 {
     26     while (Son[x][1]) x=Son[x][1]; 
     27     return Val[x];
     28 }
     29 
     30 void Rotate(int x)
     31 {
     32     int wh=Get(x);
     33     int fa=Father[x], fafa=Father[fa];
     34     if (fafa) Son[fafa][Son[fafa][1]==fa]=x;
     35     Son[fa][wh]=Son[x][wh^1]; Father[fa]=x;
     36     if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
     37     Son[x][wh^1]=fa; Father[x]=fafa;
     38     Update(fa); Update(x);
     39 }
     40 
     41 void Splay(int x)
     42 {
     43     for (int fa; (fa=Father[x]); Rotate(x))
     44         if (Father[fa])
     45             Rotate(Get(fa)==Get(x)?fa:x);
     46     Root[ID[x]]=x;
     47 }
     48 
     49 void Insert(int x,int y,int v)
     50 {
     51     int now=Root[ID[y]],fa=0;
     52     while (1)
     53     {
     54         fa=now,now=Son[now][v>Val[now]];
     55         if (now==0) 
     56         {
     57             Val[x]=v; Size[x]=1; Father[x]=fa; ID[x]=ID[y];
     58             Son[fa][v>Val[fa]]=x; Splay(x); return;
     59         }
     60     }
     61 }
     62 
     63 void Delete(int x)
     64 {
     65     Splay(x);
     66     if (!Son[Root[ID[x]]][0] && !Son[Root[ID[x]]][1])
     67     {
     68         Clear(Root[ID[x]]);
     69         Root[ID[x]]=0;
     70         return;
     71     }
     72     if (!Son[Root[ID[x]]][0])
     73     {
     74         Root[ID[x]]=Son[Root[ID[x]]][1];
     75         Clear(Father[Root[ID[x]]]);
     76         Father[Root[ID[x]]]=0;
     77         return;
     78     }
     79     if (!Son[Root[ID[x]]][1])
     80     {
     81         Root[ID[x]]=Son[Root[ID[x]]][0];
     82         Clear(Father[Root[ID[x]]]);
     83         Father[Root[ID[x]]]=0;
     84         return;
     85     }
     86     int oldroot=Root[ID[x]];
     87     int pre=Pre(Root[ID[x]]);
     88     Splay(pre);
     89     Son[Root[ID[x]]][1]=Son[oldroot][1];
     90     Father[Son[oldroot][1]]=Root[ID[x]];
     91     Clear(oldroot);
     92     Update(Root[ID[x]]);
     93 }
     94 
     95 void Merge(int x,int y)
     96 {
     97     if (Son[x][0]) Merge(Son[x][0],y);
     98     if (Son[x][1]) Merge(Son[x][1],y);
     99     int val=Val[x]+Add[ID[x]]-Add[ID[y]]; Clear(x);
    100     Insert(x,y,val); 
    101 }
    102 
    103 int main()
    104 {
    105     scanf("%d",&n);
    106     for (int i=1; i<=n; ++i)
    107     {
    108         scanf("%d",&x);
    109         ID[i]=i; Val[i]=x; Max[i]=x; 
    110         Root[i]=i; Size[i]=1; Heap.push(x);
    111     }
    112     scanf("%d",&m);
    113     for (int i=1; i<=m; ++i)
    114     {
    115         scanf("%s",opt);
    116         if (opt[0]=='U')
    117         {
    118             scanf("%d%d",&x,&y);
    119             if (ID[x]!=ID[y]) 
    120             {
    121                 Del.push(min(Max[ID[x]],Max[ID[y]]));
    122                 if (Size[Root[ID[x]]]>Size[Root[ID[y]]]) swap(x,y);
    123                 Max[ID[y]]=max(Max[ID[y]],Max[ID[x]]);
    124                 Merge(Root[ID[x]],Root[ID[y]]);
    125             }
    126         }
    127             
    128         if (opt[0]=='A' && opt[1]=='1')
    129         {
    130             scanf("%d%d",&x,&v);
    131             int val=Val[x]+v;
    132             if (Size[Root[ID[x]]]==1)
    133             {
    134                 Val[x]=val;
    135                 Del.push(Max[ID[x]]);
    136                 Max[ID[x]]=val+Add[ID[x]];
    137                 Heap.push(Max[ID[x]]);
    138                 continue;
    139             }
    140             Delete(x); Insert(x,Root[ID[x]],val);
    141             Del.push(Max[ID[x]]);
    142             Max[ID[x]]=Get_Max(Root[ID[x]])+Add[ID[x]];
    143             Heap.push(Max[ID[x]]);
    144         }
    145         
    146         if (opt[0]=='A' && opt[1]=='2')
    147         {
    148             scanf("%d%d",&x,&v), Add[ID[x]]+=v;
    149             Del.push(Max[ID[x]]);
    150             Max[ID[x]]=Get_Max(Root[ID[x]])+Add[ID[x]];
    151             Heap.push(Max[ID[x]]);
    152         }
    153             
    154         if (opt[0]=='A' && opt[1]=='3')
    155             scanf("%d",&v),ALL+=v;
    156             
    157         if (opt[0]=='F' && opt[1]=='1')
    158             scanf("%d",&x), printf("%d
    ",Val[x]+Add[ID[x]]+ALL);
    159             
    160         if (opt[0]=='F' && opt[1]=='2')
    161         {
    162             scanf("%d",&x), printf("%d
    ",Max[ID[x]]+ALL);
    163         }
    164         
    165         if (opt[0]=='F' && opt[1]=='3')
    166         {
    167             while ((!Heap.empty()) && (!Del.empty()) && Heap.top()==Del.top())
    168                 Heap.pop(), Del.pop();
    169             printf("%d
    ",Heap.top()+ALL);
    170         }
    171     }
    172 }
  • 相关阅读:
    日期处理工具类
    本地存储
    wangeditor富文本编辑器的使用
    vue+axios 拦截器及使用
    angular引入bootstrap-slider无效问题
    解决vscode导致电脑卡顿问题
    vue组件
    vue框架制作TodoList
    vue框架
    jQuery系列09
  • 原文地址:https://www.cnblogs.com/refun/p/9540169.html
Copyright © 2020-2023  润新知