• bzoj2333 [SCOI2011]棘手的操作


      用set维护每个联通块里的最值,multiset维护所有块里的最值,并查集维护连通性,然后随便搞搞就行了,合并时候采用启发式合并。复杂度O(nlognlogn),大概勉强过的程度,反正跑的很慢就是了。

      代码

      1 #include<cstdio>
      2 #include<set>
      3 #define mp make_pair
      4 #define fi first
      5 #define sc second
      6 using namespace std;
      7 const int N = 601010;
      8 int f[N],add[N],n,i,a[N],q,u,v,cnt;
      9 set<pair<int,int> > s[N];
     10 set<pair<int,int> >::iterator it;
     11 multiset<int> S;
     12 multiset<int>::iterator It;
     13 char str[3];
     14 int gf(int x)
     15 {
     16     int p=x,t;
     17     while (p!=f[p]) p=f[p];
     18     while (x!=p)
     19     {
     20         t=f[x];f[x]=p;x=t;
     21     }
     22     return p;
     23 }
     24 int main()
     25 {
     26     scanf("%d",&n);
     27     for (i=1;i<=n;i++) 
     28     {
     29         scanf("%d",&a[i]);
     30         f[i]=i;
     31         s[i].insert(mp(a[i],i));
     32         S.insert(a[i]);
     33     }
     34     scanf("%d",&q);
     35     for (i=1;i<=q;i++)
     36     {
     37         scanf("%s",str);
     38         if (str[0]=='F')
     39         {
     40             if (str[1]=='1')
     41             {
     42                 scanf("%d",&u);
     43                 printf("%d
    ",a[u]+add[gf(u)]+cnt);
     44             }
     45             else
     46             if (str[1]=='2')
     47             {
     48                 scanf("%d",&u);
     49                 printf("%d
    ",(*(--s[gf(u)].end())).fi+add[gf(u)]+cnt);
     50             }
     51             else
     52                 printf("%d
    ",*(--S.end())+cnt);
     53         }
     54         
     55         if (str[0]=='A')
     56         {
     57             if (str[1]=='1')
     58             {
     59                 scanf("%d%d",&u,&v);
     60                 S.erase(S.find((*(--s[gf(u)].end())).fi+add[gf(u)]));
     61                 s[gf(u)].erase(mp(a[u],u));
     62                 a[u]+=v;
     63                 s[gf(u)].insert(mp(a[u],u));
     64                 S.insert((*(--s[gf(u)].end())).fi+add[gf(u)]);
     65             }
     66             else
     67             if (str[1]=='2')
     68             {
     69                 scanf("%d%d",&u,&v);
     70                 S.erase(S.find((*(--s[gf(u)].end())).fi+add[gf(u)]));
     71                 add[gf(u)]+=v;
     72                 S.insert((*(--s[gf(u)].end())).fi+add[gf(u)]);
     73             }
     74             else
     75             {
     76                 scanf("%d",&u);
     77                 cnt+=u;
     78             }
     79         }
     80         
     81         if (str[0]=='U')
     82         {
     83             scanf("%d%d",&u,&v);
     84             u=gf(u);v=gf(v);
     85             if (u!=v)
     86             {
     87                 if (s[u].size()>s[v].size()) u^=v^=u^=v;
     88                 S.erase(S.find((*(--s[gf(u)].end())).fi+add[gf(u)]));
     89                 S.erase(S.find((*(--s[gf(v)].end())).fi+add[gf(v)]));
     90                 f[u]=v;
     91                 for (it=s[u].begin();it!=s[u].end();it++)
     92                 {
     93                     a[(*it).sc]=(*it).fi+add[u]-add[v];
     94                     s[v].insert(mp(a[(*it).sc],(*it).sc));
     95                 }
     96                 S.insert((*(--s[gf(v)].end())).fi+add[gf(v)]);
     97                 s[u].clear();
     98             }
     99         }
    100     }
    101 }
  • 相关阅读:
    c# GDI+中发生一般性错误的解决办法
    AutoMapper ProjectTo 与 Mapster ProjectToType
    c# 无法加载 DLL“SQLite.Interop.DLL”: 找不到指定的模块
    c# 剪裁图片
    c# System.InvalidOperationException:“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
    如何生成自己的二维码qrcode模块的使用
    Firefox20 到 Firefox21 的一个小改变
    修改document.domain的注意事项
    ✍59 300I显卡测试总结
    ✍57 PiPy上传模块&Linux 拆分合并
  • 原文地址:https://www.cnblogs.com/fzmh/p/5487284.html
Copyright © 2020-2023  润新知