首页 > 其他 > 详细

bzoj2333: [SCOI2011]棘手的操作

时间:2015-10-18 22:43:27      阅读:409      评论:0      收藏:0      [点我收藏+]

左偏树模拟。

记录lazy[x],merge,A1与F1操作时要从堆顶向下pushdown

用multiset记录每个堆的堆顶元素,每次操作之后维护

http://www.lydsy.com/JudgeOnline/problem.php?id=2333

技术分享
/**************************************************************
    Problem: 2333
    User: 1349367067
    Language: C++
    Result: Accepted
    Time:3644 ms
    Memory:15304 kb
****************************************************************/
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define N 300011
using namespace std;
multiset<int> Set;
int n,ALL=0;
int v[N]={},fa[N]={},l[N]={},r[N]={},dis[N]={};
int lazy[N]={};
void pushdown(int x)
{
     if (lazy[x]==0) return;
     int t=lazy[x];
     if (r[x])lazy[r[x]]+=t,v[r[x]]+=t;
     if (l[x])lazy[l[x]]+=t,v[l[x]]+=t;
     lazy[x]=0;
     return;
}
int merge(int x,int y)
{
    if (x==0) return y;
    if (y==0) return x;
    if (v[x]<v[y]) swap(x,y);
    pushdown(x);
    r[x]=merge(r[x],y);
    fa[r[x]]=x;
    if (dis[r[x]]>dis[l[x]]) swap(l[x],r[x]);
    dis[x]=dis[r[x]]+1;
     
    return x;
}
/*int Q[N]={},tot=0;
void pushup(int x)
{
     tot=0;
     while (x) Q[++tot]=x,x=fa[x];
     while (tot) pushdown(Q[tot--]);
     return;
}*/
void pushup(int x)
{
     if (fa[x]!=0) pushup(fa[x]);
     pushdown(x);
}
inline int findf(int x)
{
       while (fa[x]) x=fa[x];
       return x;
}
void init()
{
     scanf("%d",&n);
     for (int i=1;i<=n;i++)
     {
         fa[i]=l[i]=r[i]=lazy[i]=dis[i]=0;
         scanf("%d",&v[i]),Set.insert(v[i]);
     }
}
void work()
{
     int m;
     int x,y,q,p,t,f;
     char ch[10];
     scanf("%d",&m);
     for (int i=1;i<=m;i++)
     {
          
         scanf("%s",ch);
         //cout<<"***"<<i<<" "<<ch[0]<<ch[1]<<endl;
         if (ch[0]==U)
         {
            scanf("%d%d",&x,&y);
            q=findf(x);p=findf(y);
            if (q==p) continue;
            t=merge(q,p);
            if (q==t) Set.erase(Set.find(v[p]));
            else Set.erase(Set.find(v[q]));
         }
         if (ch[0]==A&&ch[1]==1)
         {
            scanf("%d%d",&x,&y);
            pushup(x);
             
            q=findf(x);
            Set.erase(Set.find(v[q]));
             
            pushup(x);
            t=merge(l[x],r[x]);f=fa[x];
            l[x]=r[x]=fa[x]=0;
            if (x==l[f]) l[f]=t;
            else r[f]=t;
            fa[t]=f;t=findf(t);
            v[x]+=y;
            Set.insert(v[merge(x,t)]);
         }
         if (ch[0]==A&&ch[1]==2)
         {
            scanf("%d%d",&x,&y);
            q=findf(x);
            Set.erase(Set.find(v[q]));
            lazy[q]+=y;v[q]+=y;
            Set.insert(v[q]);
         }
         if (ch[0]==A&&ch[1]==3)
         {
            scanf("%d",&y);
            ALL+=y;
         }
         if (ch[0]==F&&ch[1]==1)
         {
            scanf("%d",&x);
             
            pushup(x);
            printf("%d\n",v[x]+ALL);
         }
         if (ch[0]==F&&ch[1]==2)
         {
            scanf("%d",&x);
            q=findf(x);
            //cout<<x<<" * "<<q<<endl;
            printf("%d\n",v[q]+ALL);
         }
         if (ch[0]==F&&ch[1]==3)
         {
            printf("%d\n",*--Set.find(1000000000)+ALL);
         }
     }
 
}
int main()
{
    init();
    work();
    return 0;
}
View Code

 

bzoj2333: [SCOI2011]棘手的操作

原文:http://www.cnblogs.com/3ZStarve/p/4890333.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!