bzoj 2333

标题就很233的题目 数据结构滑稽题

在线算法:: 可并堆维护

  太难写了 表示不爱

离线算法::带权并查集将操作离散到连续的区间上(超银河英雄传说 并查集基础训练题)  线段树处理之 比较simple

  1 #include <bits/stdc++.h>
  2 #define N 300010
  3 using namespace std;
  4
  5 inline int read()
  6 {
  7     int x=0,f=1;
  8     char ch=getchar();
  9     while(ch<‘0‘||ch>‘9‘)
 10     {
 11         if(ch==‘-‘)f=-1;
 12         ch=getchar();
 13     }
 14     while(ch>=‘0‘&&ch<=‘9‘)
 15     {
 16         x=x*10+ch-‘0‘;
 17         ch=getchar();
 18     }
 19     return x*f;
 20 }
 21 struct query_struc
 22 {
 23     int tp,x,v;
 24     int sf,sta;
 25 } que[N];
 26 int tree[N<<2],tag[N<<2],A[N],vis[N];
 27 int n,q,fa[N],s[N],sz[N],pl[N],ks[N],S[N];
 28 int findfa(int x)
 29 {
 30     if(fa[x]==x)
 31         return x;
 32     int tt=findfa(fa[x]);
 33     S[x]+=S[fa[x]];
 34     fa[x]=tt;
 35     return fa[x];
 36 }
 37 inline void pushup(int rt)
 38 {
 39     tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
 40 }
 41 inline void pushdown(int rt)
 42 {
 43     if(tag[rt]!=0)
 44     {
 45         tree[rt<<1]+=tag[rt];
 46         tree[rt<<1|1]+=tag[rt];
 47         tag[rt<<1]+=tag[rt];
 48         tag[rt<<1|1]+=tag[rt];
 49         tag[rt]=0;
 50     }
 51 }
 52 void built(int l,int r,int rt)
 53 {
 54     if(l==r)
 55     {
 56         tree[rt]=A[pl[l]];
 57         return ;
 58     }
 59     int mid=(l+r)>>1;
 60     built(l,mid,rt<<1);
 61     built(mid+1,r,rt<<1|1);
 62     pushup(rt);
 63 }
 64 void modify(int L,int R,int x,int l,int r,int rt)
 65 {
 66     if(L<=l&&r<=R)
 67     {
 68         tree[rt]+=x;
 69         tag[rt]+=x;
 70         return ;
 71     }
 72     int mid=(l+r)>>1;
 73     pushdown(rt);
 74     if(L<=mid) modify(L,R,x,l,mid,rt<<1);
 75     if(R>mid) modify(L,R,x,mid+1,r,rt<<1|1);
 76     pushup(rt);
 77 }
 78 int query(int L,int R,int l,int r,int rt)
 79 {
 80     if(L<=l&&r<=R) return tree[rt];
 81     int mid=(l+r)>>1,ans=-999999999;
 82     pushdown(rt);
 83     if(L<=mid) ans=max(ans,query(L,R,l,mid,rt<<1));
 84     if(R>mid ) ans=max(ans,query(L,R,mid+1,r,rt<<1|1));
 85     return ans;
 86 }
 87 int main()
 88 {
 89 //    freopen("read.in","r",stdin);
 90 //    freopen("wro.out","w",stdout);
 91     n=read();
 92     for(int i=1; i<=n; i++) fa[i]=i,sz[i]=1;
 93     for(int i=1; i<=n; i++) A[i]=read();
 94     q=read();
 95     for(int i=1; i<=q; i++)
 96     {
 97         char ch[50];
 98         scanf("%s",ch);
 99         if(ch[0]==‘A‘)
100         {
101             que[i].tp=ch[1]-‘0‘;
102             if(ch[1]!=‘3‘)
103             {
104                 que[i].x=read();
105                 que[i].v=read();
106                 que[i].sf=sz[findfa(que[i].x)];
107                 que[i].sta=fa[que[i].x];
108             }
109             else que[i].v=read();
110         }
111         if(ch[0]==‘F‘)
112         {
113             que[i].tp=3+ch[1]-‘0‘;
114             if(ch[1]!=‘3‘)
115             {
116                 que[i].x=read();
117                 que[i].sf=sz[findfa(que[i].x)];
118                 que[i].sta=fa[que[i].x];
119             }
120         }
121
122         if(ch[0]==‘U‘)
123         {
124             int x=read(),y=read();
125             int f1=findfa(x),f2=findfa(y);
126             if(f1==f2) continue;
127             fa[f2]=f1;
128             S[f2]=sz[f1];
129             sz[f1]+=sz[f2];
130         }
131     }
132     int tot=0;
133     for(int i=1; i<=n; i++)
134     {
135         int x=findfa(i);
136         if(!vis[x])
137         {
138             vis[x]=1;
139             ks[x]=tot;
140             tot+=sz[x];
141         }
142         s[i]=S[i]+ks[x];
143     }
144     for(int i=1; i<=n; i++) pl[s[i]+1]=i;
145     //check_print();
146     built(1,n,1);
147     for(int i=1; i<=q; i++)
148     {
149         int x=que[i].x,v=que[i].v,sf=que[i].sf;
150         int sta=que[i].sta;
151         if(!que[i].tp) continue;
152         if(que[i].tp==1)
153             modify(s[x]+1,s[x]+1,v,1,n,1);
154         else if(que[i].tp==2)
155             modify(s[sta]+1,s[sta]+sf,v,1,n,1);
156         else if(que[i].tp==3)
157             modify(1,n,v,1,n,1);
158         else if(que[i].tp==4)
159             printf("%d\n",query(s[x]+1,s[x]+1,1,n,1));
160         else if(que[i].tp==5)
161             printf("%d\n",query(s[sta]+1,s[sta]+sf,1,n,1));
162         else printf("%d\n",tree[1]);
163     }
164     return 0;
165 }

ps: 原先wa了一发,但和黄学长的都拍上了 结果是建线段树初始权值没处理好 且dmk 偷懒初始值都赋成了0

因此 还是写的时候要仔细

时间: 2024-08-10 08:57:35

bzoj 2333的相关文章

[bzoj 2333] 棘手的操作[SCOI2011]

2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2538  Solved: 986[Submit][Status][Discuss] Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: 将第x个节点的权值增加v A2 x v: 将第x个节点所在的连通块的所有

bzoj 2333 棘手的操作(线段树)

题外话 昨天粗去浪了一天,打麻将输了一下午真是拙计啊 这个题号2333真是2333,有爱无比 晚上回家把这题写了,1A,还算不错 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y:加一条边,连接第x个节点和第y个节点 A1 x v:将第x个节点的权值增加v A2 x v:将第x个节点所在的连通块的所有节点的权值都增加v A3 v:将所有节点的权值都增加v F1 x:输出第x个节点当前的权值 F2 x:

BZOJ 2333 SCOI2011 棘手的操作 可并堆套可并堆

题目大意:给定n个节点,每个节点有一个初始权值,维护以下操作: 1.合并两个联通块 2.某个点权值+x 3.某个点所在联通块权值+x 4.所有点权值+x 5.询问某个点的权值 6.询问某个点所在联通块的最大权值 7.询问所有点之间的最大权值 2333333333333333333333333333333333333333333333333333333333333 2333333333333333333333333333333333333333333333333333333333333 23333

[BZOJ 2333] 棘手的操作 可并堆

实现 1. 可并堆 1.1. 可并堆的树高并不是 O(log n) 的. 例如我来一个极端数据, 从前往后逐个插入:  n n-1 n-2 ... 5 4 3 2 1 1.2. c[N][2], par[N] 的维护技巧 1.2.1. 注意两者是绑在一起的, 维护一个的时候要同时维护另一个. 1.2.2. 注意是否存在儿子, 是否存在父亲, 否则 par[0] = x , 就会导致一系列可怕的问题. 2. multiset 对于 int 类型的变量 x , erase(x) 表示删除权值为 x

BZOJ 2333 SCOI 2011 棘手的操作 可并堆

做此题的原因 题号美 题目大意 给出一个序列,支持一堆操作(具体看下面).让你维护它. 思路 U x y:我们需要可并堆来将两个堆合并. A1 x v:将这个点从堆中拽出来,改了之后再合并回去. A2 x v:在堆顶打标记. A3:记录一个全局变量记录. F1 x:将这个点到堆顶的链上的所有标记下传,之后返回自己的大小. F2 x:返回堆顶. F3:用一个堆(set也行)维护所有堆顶的元素.需要仔细讨论一下. CODE #define _CRT_SECURE_NO_WARNINGS #inclu

BZOJ 2333 SCOI2011 棘手的操作 并查集+可并堆

..题意概述就不写了,各位老爷如果是看着玩的可以去搜一下,如果是做题找来的也知道题干的.实际上是题干无法缩减懒得复制ORZ 首先处理一下集合的合并和单点值查询的问题.使用并查集,对于每个点记录标记d表示这个点的实际值比这个点加入并查集的时候的值w大了多少,对于每个点find的时候把这个点到代表元路径上的点的d(不包括代表元)的d加起来更新这个点的d,每一次查询某个点的当前值的时候就先find就可以直接用w+d+代表元的d(特判这个点是不是代表元)回答.特别注意为了保证正确性在merge的时候要把

【BZOJ】2333: [SCOI2011]棘手的操作

http://www.lydsy.com/JudgeOnline/problem.php?id=2333 #include <bits/stdc++.h> using namespace std; const int N=300015, Lim=N; struct node *null; struct node { node *c[2], *f; int s, tag, mx, w; void init(int _w=-(~0u>>2)) { c[0]=c[1]=f=null; s

【BZOJ】【1021】【SHOI2008】Dept循环的债务

DP 去膜拜题解了>_>玛雅原来是动规…… 让我先理解一下为什么要用动规:这个题根据钱数推方案其实是无从下手的……(线性规划?……事实证明我想多了) 啦-我们先来看个超级简化版的问题:怎么判无法还清?正着判很麻烦对不对= =(其实是我没想……) 那么我们倒着来考虑:有哪些状态是我们通过交换钱币能够到达的,这个可以递推对不>_> 现在我们就知道哪些状态我们是可以到达的了……再多想一下……递推……如果我们依次考虑每种面额的交换策略,顺便也就知道了我们到达这个状态的最小交换次数对吧? 原

BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数(数位DP+恶心细节)

BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 Time Limit: 5 Sec  Memory Limit: 64 MB Description 正如你所知,奶牛们没有手指以至于不能玩“石头剪刀布”来任意地决定例如谁先挤奶的顺序.她们甚至也不能通过仍硬币的方式. 所以她们通过"round number"竞赛的方式.第一头牛选取一个整数,小于20亿.第二头牛也这样选取一个整数.如果这两个数都是 "round numbers"