码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2333 [SCOI2011]棘手的操作

时间:2016-05-13 12:14:23      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:

  用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\n",a[u]+add[gf(u)]+cnt);
 44             }
 45             else
 46             if (str[1]==2)
 47             {
 48                 scanf("%d",&u);
 49                 printf("%d\n",(*(--s[gf(u)].end())).fi+add[gf(u)]+cnt);
 50             }
 51             else
 52                 printf("%d\n",*(--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 }

 

bzoj2333 [SCOI2011]棘手的操作

标签:

原文地址:http://www.cnblogs.com/fzmh/p/5487284.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!