前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >洛谷P3273 [SCOI2011]棘手的操作

洛谷P3273 [SCOI2011]棘手的操作

作者头像
attack
发布2018-04-11 14:46:21
5950
发布2018-04-11 14:46:21
举报

题目描述

有N个节点,标号从1到N,这N个节点一开始相互不连通。第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权值增加vA2 x v: 将第x个节点所在的连通块的所有节点的权值都增加vA3 v: 将所有节点的权值都增加vF1 x: 输出第x个节点当前的权值F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值F3: 输出所有节点中,权值最大的节点的权值

输入输出格式

输入格式:

输入的第一行是一个整数N,代表节点个数。接下来一行输入N个整数,a[1], a[2], ..., a[N],代表N个节点的初始权值。再下一行输入一个整数Q,代表接下来的操作数。最后输入Q行,每行的格式如题目描述所示。

输出格式:

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

输入输出样例

输入样例#1

代码语言:javascript
复制
3
0 0 0
8
A1 3 -20
A1 2 20
U 1 3
A2 1 10
F1 3
F2 3
A3 -10
F3

输出样例#1:

代码语言:javascript
复制
-10
10
10

说明

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

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

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

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

开两个可并堆堆

分别维护联通快最大值和所有的最大值

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

直接合并

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

先删掉,再加上原来的权值加v

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

跟线段树一样打个标记

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

直接用一个变量记录

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

直接输出

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

找到父亲,输出

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

输出维护最大值的那个堆的根节点

效率暂时rank1

代码语言:javascript
复制
  1 #include<cstdio>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<queue>
  6 using namespace std;
  7 const int MAXN=300010;
  8 #define ls T[x].ch[0]
  9 #define rs T[x].ch[1]
 10 inline int read()
 11 {
 12     int a;
 13     cin>>a;
 14     return a;
 15 }
 16 int root,N,All;
 17 struct Priority
 18 {
 19     struct node
 20     {
 21         int fa,dis,val,ch[2],mark;
 22     }T[MAXN];
 23     void Clear(int x){ls=rs=0;T[x].fa=0;}
 24     void Pushdown(int x)
 25     {
 26         if(ls) T[ls].val+=T[x].mark,T[ls].mark+=T[x].mark;
 27         if(rs) T[rs].val+=T[x].mark,T[rs].mark+=T[x].mark;
 28         T[x].mark=0;
 29     }
 30     int Merge(int x,int y)
 31     {
 32         if(!x||!y)    return x+y;
 33         if( T[x].val < T[y].val)    swap(x,y);
 34         Pushdown(x);
 35         rs=Merge(rs,y);
 36         T[rs].fa=x;
 37         if(T[rs].dis>T[ls].dis) swap(ls,rs);
 38         T[x].dis=T[rs].dis+1;
 39         return x;
 40     }
 41     int Delet(int x)
 42     {
 43         Pushdown(x);
 44         int q=T[x].fa,p=Merge(ls,rs);
 45         T[p].fa=q;
 46         T[q].ch[ T[q].ch[1] == x] = p;
 47         while(q)
 48         {
 49             if(T[ T[q].ch[0] ].dis < T[ T[q].ch[1] ].dis)   swap( T[q].ch[0] , T[q].ch[1] );
 50             if(T[ T[q].ch[1] ].dis+1 == T[q].dis)   return root;
 51             T[q].dis=T[ T[q].ch[1] ].dis+1;
 52             p=q;q=T[q].fa;
 53         }
 54         return p;
 55     }
 56     int Find(int x)
 57     {
 58         while(T[x].fa) x=T[x].fa;
 59         return x;
 60     }
 61     int Sum(int x)
 62     {
 63         int ans=0;
 64         while(x=T[x].fa)  ans+=T[x].mark;
 65         return ans;
 66     }
 67     int AddPoint(int x,int v)
 68     {
 69         int fx=Find(x);
 70         if(fx==x)
 71         {
 72             if(ls+rs==0) 
 73                 {T[x].val+=v;return x;}
 74             else 
 75                 if(ls)  fx=ls;
 76                 else     fx=rs;
 77         }
 78         Delet(x);
 79         T[x].val+=v+Sum(x);
 80         Clear(x);
 81         return Merge(Find(fx),x);
 82     }
 83     int Build()
 84     {
 85         queue<int>q;
 86         for(int i=1;i<=N;i++)  
 87             q.push(i);
 88         while(q.size()>1)
 89         {
 90             int x=q.front();q.pop();
 91             int y=q.front();q.pop();
 92             int z=Merge(x,y);
 93             q.push(z);
 94         }
 95         return q.front();
 96     }
 97 };
 98 Priority h1,h2;
 99 int main()
100 { 
101     #ifdef WIN32
102     freopen("a.in","r",stdin);
103     freopen("b.out","w",stdout);
104     #else
105     #endif
106     char opt[20];
107     N=read();
108     h1.T[0].dis=h2.T[0].dis=-1;
109     for(int i=1;i<=N;i++)
110         h2.T[i].val=h1.T[i].val=read();
111     root=h2.Build();
112     int M=read();
113     while(M--)
114     {
115         scanf("%s",opt+1);
116         if(opt[1]=='U')
117         {
118             int x=read(),y=read();
119             int fx=h1.Find(x),fy=h1.Find(y);
120             if(fx!=fy)
121             {
122                    int tmp=h1.Merge(fx,fy);
123                 if(tmp==fx) root=h2.Delet(fy);
124                 else         root=h2.Delet(fx);//优化,根据大根堆的性质,以后的就没有用了    
125             }
126         }
127         else if(opt[1]=='A')
128         {
129             if(opt[2]=='1')
130             {
131                 int x=read(),v=read();
132                 root=h2.Delet(h1.Find(x));
133                 int y=h1.AddPoint(x,v);
134                 h2.T[y].val=h1.T[y].val;
135                 h2.Clear(y);
136                 root=h2.Merge(root,y);
137             }
138             else if(opt[2]=='2')
139             {
140                 int x=read(),v=read();
141                 int fx=h1.Find(x);
142                 root=h2.Delet(fx);
143                 h1.T[fx].val+=v;
144                 h1.T[fx].mark+=v;
145                 h2.T[fx].val=h1.T[fx].val;
146                 h2.Clear(fx);
147                 root=h2.Merge(root,fx);
148             }
149             else if(opt[2]=='3')
150             {
151                 int v=read();
152                 All+=v;
153             }
154             
155         }
156         else if(opt[1]=='F')
157         {
158             if(opt[2]=='1')
159             {
160                 int x=read();
161                 printf("%d\n",h1.T[x].val+h1.Sum(x)+All);
162             }
163             else if(opt[2]=='2')
164             {
165                 int x=read();
166                 printf("%d\n",h1.T[h1.Find(x)].val+All);
167             }
168             else if(opt[2]=='3')
169                 printf("%d\n",h2.T[root].val+All);
170         }
171     }
172 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
  • 输入输出格式
  • 输入输出样例
  • 说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档