• BZOJ2333: [SCOI2011]棘手的操作


    2333: [SCOI2011]棘手的操作

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2537  Solved: 985
    [Submit][Status][Discuss]

    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

    2.SCOI2011棘手的操作

    完成时间:2017.7.23.21.35

    时耗:3h

    思路{

      题号有点小牛逼。。。。。。。。。

      看到合并,查询最大值,我们果断想到了可并堆。

      操作1:合并两个左偏树,找出两个节点所属的左偏树,合并即可

      操作2:给一特定节点的值增加v,我们可以先取出这个元素,修改它的值,合并。

      操作3:给一个左偏树的所有值增加一个数,像线段树那样打个标记都可以了。

      操作4;直接搞个全局变量记录all都可以辣。

      查询1:输出x节点的权值=当前的值加上跳父亲的lazy+全局all

      查询2:直接取堆顶元素即可。

      查询3:这个只要取各个堆的堆顶元素建一个堆,在各种操作中先删除,再单点修改,再插入。

    }

    //第一次写可并堆的数据结构火题,还是写下注释吧。。。。。。
    #include<bits/stdc++.h>
    #define RG register
    #define il inline 
    #define N 300010
    using namespace std;
    int l1[N],r1[N],d1[N],d2[N],v1[N],lazy[N],l2[N],r2[N],v2[N],f1[N],f2[N],rt,n,q,all;
    void down(int x){
      v1[l1[x]]+=lazy[x],v1[r1[x]]+=lazy[x];
      lazy[l1[x]]+=lazy[x],lazy[r1[x]]+=lazy[x];
      lazy[x]=0;
    }//下放懒标记。。
    int find1(int x){int X=x;while(f1[X])X=f1[X];return X;}//找霸霸
    int sum(int x){int sum=0,X=f1[x];while(X)sum+=lazy[X],X=f1[X];return sum;}//累加LAZY
    int merge1(int x,int y){//大根堆
      if(!x||!y)return x+y;
      if(v1[x]<v1[y])swap(x,y);
      down(x);r1[x]=merge1(r1[x],y);f1[r1[x]]=x;
      if(d1[r1[x]]>d1[l1[x]])swap(r1[x],l1[x]);
      d1[x]=d1[r1[x]]+1;return x;
    }
    int merge2(int x,int y){
      if(!x||!y)return x+y;
      if(v2[x]<v2[y])swap(x,y);
      r2[x]=merge2(r2[x],y);f2[r2[x]]=x;
      if(d2[r2[x]]>d2[l2[x]])swap(r2[x],l2[x]);
      d2[x]=d2[r2[x]]+1;return x;
    }
    int del1(int x){down(x);
      int le=l1[x],ri=r1[x];int y=merge1(le,ri);
      if(x==l1[f1[x]])l1[f1[x]]=y;else r1[f1[x]]=y;
      f1[y]=f1[x];return find1(y);
    }
    void del2(int x){
      int le=l2[x],ri=r2[x];int y=merge2(le,ri);
      if(rt==x)rt=y;
      if(x==l2[f2[x]])l2[f2[x]]=y;else r2[f2[x]]=y;
      f2[y]=f2[x];
    }
    void getnode1(int x,int v){f1[x]=d1[x]=l1[x]=r1[x]=0,v1[x]=v;}
    void getnode2(int x,int v){f2[x]=d2[x]=l2[x]=r2[x]=0,v2[x]=v;}
    void U(){
      int x,y;scanf("%d%d",&x,&y);
      x=find1(x),y=find1(y);
      if(x!=y){
        if(merge1(x,y)==x)del2(y);else del2(x);
      }
    }
    void A1(){
      int x,v;scanf("%d%d",&x,&v);
      del2(find1(x));//堆顶元素可能不是最优的了。。。。。
      int y=del1(x);
      getnode1(x,v+v1[x]+sum(x));
      int z=merge1(y,x);getnode2(z,v1[z]);
      rt=merge2(rt,z);
    }
    void A2(){
      int x,v;scanf("%d%d",&x,&v);
      x=find1(x);v1[x]+=v;lazy[x]+=v;
      del2(x);getnode2(x,v1[x]);rt=merge2(rt,x);
    }
    void A3(){int v;scanf("%d",&v);all+=v;}
    void F1(){int x;scanf("%d",&x);printf("%d
    ",v1[x]+sum(x)+all);}
    void F2(){int x;scanf("%d",&x);printf("%d
    ",v1[find1(x)]+all);}
    void F3(){printf("%d
    ",v2[rt]+all);}
    int main(){
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      scanf("%d",&n);
      for(int i=1;i<=n;++i)scanf("%d",&v1[i]),v2[i]=v1[i];
      scanf("%d",&q);rt=1;for(int i=2;i<=n;++i)rt=merge2(rt,i);char ch[3];
      for(int i=1;i<=q;++i){
        scanf("%s",ch);
        if(ch[0]=='U')U();
        if(ch[0]=='A'){
          if(ch[1]=='1')A1();
          if(ch[1]=='2')A2();
          if(ch[1]=='3')A3();
        }
        if(ch[0]=='F'){
          if(ch[1]=='1')F1();
          if(ch[1]=='2')F2();
          if(ch[1]=='3')F3();
        }
      }return 0;
    }
    

      

  • 相关阅读:
    面试官:反射都不会,还敢说自己会Java?
    nginx 开启x-forward
    不写代码,从0到1教你制作炫酷可视化大屏
    5G 专网部署方案
    Mac运行pygame一直显示空白屏幕
    数据库大咖解读“新基建”,墨天轮四重好礼相送!
    Oracle 20c 新特性:自动的区域图
    4000多人全靠报表自动化,效率提高60%,这套数据平台方法论真强
    EBS开发性能优化之查找需要优化的程序
    EBS开发性能优化之SQL语句优化
  • 原文地址:https://www.cnblogs.com/zzmmm/p/7226263.html
Copyright © 2020-2023  润新知