• 真--可并堆模板--BZOJ2333: [SCOI2011]棘手的操作


    n<=300000个点,开始是独立的,m<=300000个操作:

    方法一:单点修改、查询,区间修改、查询?等等等等这里修改是块修改不是连续的啊,那就让他连续呗!具体方法:离线后,每次连接两棵树u,v时,把v放到u树根节点的最后,使其dfs序最后,最后扫一次把每棵树dfs一下搞出这个序列,然后线段树操作即可。

    怎么把v放到u的儿子最后???强制一下连边顺序!!根据你写的邻接表,决定过程中的边是要正连还是倒连以达到目标顺序。有点抽象,见代码。

    没写。

    方法二:真正“棘手的操作”--可并堆!!!

    如果是散散的点再连起来,可并堆的期望深度是小小的,可以做标记下传的!!

    大体的思路是,每个块一个堆,然后每个堆的根节点的值再搞一个堆,就可以回答所有询问。然后来看看怎么操作:

    U:直接合并。

    A1:单点加,那就相当于单点查,单点删,单点加。单点删和单点加详见

    单点查的话就标记下传就行了。。

    A2:块加,打标记。

    A3:是来搞笑的吗,记个全局变量。

    F1:单点查,同上。

    F2,F3:来搞笑的。

    总之,重点在于:两个堆同时操作。

    这次复合数据结构题的整体构思比以前有进步,但!!可并堆和并查集的结合非常混乱,这题要再写。

      1 #include<string.h>
      2 #include<stdlib.h>
      3 #include<stdio.h>
      4 #include<math.h>
      5 //#include<assert.h>
      6 #include<algorithm>
      7 //#include<iostream>
      8 using namespace std;
      9 
     10 int n,m;
     11 #define maxn 300011
     12 struct leftist
     13 {
     14     struct Node
     15     {
     16         int fa,ls,rs,v,dis,add;
     17     }a[maxn];
     18     leftist() {a[0].dis=-1;}
     19     void addsingle(int x,int v)
     20     {
     21         if (!x) return;
     22         (a[x].v+=v);
     23         a[x].add+=v;
     24     }
     25     void down(int x)
     26     {
     27         int &p=a[x].ls,&q=a[x].rs;
     28         if (a[x].add) {addsingle(p,a[x].add); addsingle(q,a[x].add); a[x].add=0;}
     29     }
     30     int sta[maxn];
     31     void download(int x)
     32     {
     33         int top=0;
     34         for (int i=x;i;i=a[i].fa) sta[++top]=i;
     35         for (;top;top--) down(sta[top]);
     36     }
     37     int merge(int x,int y)
     38     {
     39         if (!x || !y) return x^y;
     40         if (a[x].v<a[y].v) {int t=x; x=y; y=t;}
     41         down(x);
     42         a[x].rs=merge(a[x].rs,y);
     43         if (a[a[x].ls].dis<a[a[x].rs].dis) {int t=a[x].ls; a[x].ls=a[x].rs; a[x].rs=t;}
     44         a[x].dis=a[a[x].rs].dis+1;
     45         if (a[x].rs) a[a[x].rs].fa=x; if (a[x].ls) a[a[x].ls].fa=x;
     46         return x;
     47     }
     48     void Delete(int &root,int x)
     49     {
     50         int y=a[x].fa,w=(x==a[y].rs); x=merge(a[x].ls,a[x].rs); a[x].fa=y;
     51         if (!y) {root=x; return;}
     52         if (w) a[y].rs=x; else a[y].ls=x;
     53         if (a[a[y].ls].dis<a[a[y].rs].dis) {int t=a[y].ls; a[y].ls=a[y].rs; a[y].rs=t;}
     54         x=a[y].rs;
     55         while (y && a[y].dis!=a[x].dis+1)
     56         {
     57             a[y].dis=a[x].dis+1;
     58             x=y; y=a[y].fa;
     59             if (a[a[y].ls].dis<a[a[y].rs].dis) {int t=a[y].ls; a[y].ls=a[y].rs; a[y].rs=t;}
     60             x=a[y].rs;
     61         }
     62     }
     63     void push(int id,int &root,int val)
     64     {
     65         a[id].fa=a[id].ls=a[id].rs=a[id].dis=a[id].add=0; a[id].v=val;
     66         root=merge(root,id);
     67     }
     68     int top(int root) {return a[root].v;}
     69 }q,qtot;
     70 int root[maxn];
     71 int find(int x) {return x==root[x]?x:(root[x]=find(root[x]));}
     72 
     73 int main()
     74 {
     75     scanf("%d",&n);
     76     for (int i=1,x;i<=n;i++) scanf("%d",&x),q.push(i,root[i],x),qtot.push(i,root[0],x);
     77     scanf("%d",&m);
     78     char c;int x,y; int totadd=0;
     79     for (int i=1;i<=m;i++)
     80     {
     81         while ((c=getchar())!='U' && c!='A' && c!='F');
     82         if (c=='U')
     83         {
     84             scanf("%d%d",&x,&y); x=find(x); y=find(y);
     85             if (x==y) continue;
     86             qtot.Delete(root[0],y); qtot.Delete(root[0],x);
     87             root[x]=root[y]=q.merge(x,y);
     88             x=root[x]; qtot.push(x,root[0],q.a[x].v);
     89         }
     90         else if (c=='A')
     91         {
     92             c=getchar();
     93             if (c=='1')
     94             {
     95                 scanf("%d%d",&x,&y); find(x);
     96                 qtot.Delete(root[0],root[x]);
     97                 q.download(x); int tmp=q.a[x].v;
     98                 q.Delete(root[x],x); int z=root[x];
     99                 if (z) root[z]=z,q.push(x,root[z],tmp+y),root[x]=root[z];
    100                 else q.push(x,root[x],tmp+y);
    101                 qtot.push(root[x],root[0],q.a[root[x]].v);
    102             }
    103             else if (c=='2')
    104             {
    105                 scanf("%d%d",&x,&y); x=find(x); qtot.Delete(root[0],x);
    106                 q.addsingle(x,y); qtot.push(x,root[0],q.a[x].v);
    107             }
    108             else if (c=='3')
    109             {
    110                 scanf("%d",&x);
    111                 totadd+=x;
    112             }
    113         }
    114         else
    115         {
    116             c=getchar();
    117             if (c=='1')
    118             {
    119                 scanf("%d",&x);
    120                 q.download(x);
    121                 printf("%d
    ",q.a[x].v+totadd);
    122             }
    123             else if (c=='2')
    124             {
    125                 scanf("%d",&x); x=find(x);
    126                 printf("%d
    ",q.a[x].v+totadd);
    127             }
    128             else printf("%d
    ",qtot.a[root[0]].v+totadd);
    129         }
    130     }
    131     return 0;
    132 }
    View Code
  • 相关阅读:
    mysql 安装
    flying-saucer-pdf使用中字符串过长换行出问题的解决办法
    杂想
    关于MATLAB实验结果求交点问题
    关于学习方向问题
    关于读取文件夹中的图片问题
    关于ROC曲线的碎碎念
    win7(64)+vs2013+opencv3.0配置的辛酸路程
    验证模式和辨识模式
    指纹识别认证
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8270329.html
Copyright © 2020-2023  润新知