BZOJ 2333 棘手的操作(离线+线段树+带权并查集)
这题搞了我一天啊。。。拍不出错原来是因为极限数据就RE了啊,竟然返回WA啊。我的线段树要开8倍才能过啊。。。
首先可以发现除了那个加边操作,其他的操作有点像线段树啊。如果我们把每次询问的联通块都放在一个区间的话,那么就可以用线段树维护了啊。
于是我们只需要用带权并查集把联通块串成一条链的形式。就可以用区间表示出来了啊。。
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Node{char s[]; int x, y;}node[N];
struct Q{int l, r;}q[N];
int seg[N<<], tag[N<<], a[N], fa[N], to[N], tail[N], suc[N], F[N]; int find(int x){
int tmp;
if (fa[x]!=x) tmp=find(fa[x]), fa[x]=tmp;
return fa[x];
}
void union_set(int u, int v){fa[u]=v; suc[tail[v]]=u; tail[v]=tail[u];}
void union_set1(int x, int y){
int l=min(q[x].l,q[y].l), r=max(q[x].r,q[y].r);
fa[x]=y, q[y].l=l, q[y].r=r;
}
void push_up(int p){seg[p]=max(seg[p<<],seg[p<<|]);}
void push_down(int p){
if (!tag[p]) return ;
seg[p]+=tag[p];
tag[p<<]+=tag[p]; tag[p<<|]+=tag[p]; tag[p]=;
}
void init(int p, int l, int r){
if (l<r) {
int mid=(l+r)>>;
init(lch); init(rch); push_up(p);
}
else seg[p]=a[F[l]];
}
int query(int p, int l, int r, int L, int R){
push_down(p);
if (L>r||R<l) return -INF;
if (L<=l&&R>=r) return seg[p];
int mid=(l+r)>>;
return max(query(lch,L,R),query(rch,L,R));
}
void update(int p, int l, int r, int L, int R, int val){
push_down(p);
if (L>r||R<l) return ;
if (L<=l&&R>=r) tag[p]=val, push_down(p);
else {
int mid=(l+r)>>;
update(lch,L,R,val); update(rch,L,R,val); push_up(p);
}
}
int main ()
{
int n, m, u, v;
scanf("%d",&n);
FOR(i,,n) fa[i]=tail[i]=i;
FOR(i,,n) scanf("%d",a+i);
scanf("%d",&m);
FOR(i,,m) {
scanf("%s",node[i].s);
if (!strcmp(node[i].s,"U")||!strcmp(node[i].s,"A1")||!strcmp(node[i].s,"A2")) scanf("%d%d",&node[i].x,&node[i].y);
else if(!strcmp(node[i].s,"F3")) continue;
else scanf("%d",&node[i].x);
}
FOR(i,,m) if(node[i].s[]=='U') {
u=find(node[i].x), v=find(node[i].y);
if (u!=v) union_set(u,v);
}
int now=;
FOR(i,,n) if (fa[i]==i) {
to[i]=++now; F[now]=i;
int tmp=i;
while (suc[tmp]) tmp=suc[tmp], to[tmp]=++now, F[now]=tmp;
}
//debug
//FOR(i,1,n) printf(" %d",to[i]); putchar('\n');
//debug
init(,,n); FOR(i,,n) fa[i]=q[i].l=q[i].r=i;
FOR(i,,m) {
if (!strcmp(node[i].s,"U")) {
u=find(to[node[i].x]); v=find(to[node[i].y]);
if (u!=v) union_set1(u,v);
}
else if (!strcmp(node[i].s,"A1")) update(,,n,to[node[i].x],to[node[i].x],node[i].y);
else if (!strcmp(node[i].s,"A2")) u=find(to[node[i].x]), update(,,n,q[u].l,q[u].r,node[i].y);
else if (!strcmp(node[i].s,"A3")) update(,,n,,n,node[i].x);
else if (!strcmp(node[i].s,"F1")) printf("%d\n",query(,,n,to[node[i].x],to[node[i].x]));
else if (!strcmp(node[i].s,"F2")) u=find(to[node[i].x]), printf("%d\n",query(,,n,q[u].l,q[u].r));
else printf("%d\n",query(,,n,,n));
}
return ;
}
BZOJ 2333 棘手的操作(离线+线段树+带权并查集)的更多相关文章
- 2333: [SCOI2011]棘手的操作[离线线段树]
2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2325 Solved: 909[Submit][Stat ...
- BZOJ 1202 狡猾的商人 差分约束or带权并查集
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1202 题目大意: 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的 ...
- BZOJ 3376 [Usaco2004 Open]Cube Stacking 方块游戏(带权并查集)
题解 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #in ...
- 【BZOJ4025】二分图(线段树分治,并查集)
[BZOJ4025]二分图(线段树分治,并查集) 题面 BZOJ 题解 是一个二分图,等价于不存在奇环. 那么直接线段树分治,用并查集维护到达根节点的距离,只计算就好了. #include<io ...
- 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)
[CF938G]Shortest Path Queries(线段树分治,并查集,线性基) 题面 CF 洛谷 题解 吼题啊. 对于每个边,我们用一个\(map\)维护它出现的时间, 发现询问单点,边的出 ...
- BZOJ4025 二分图 线段树分治、带权并查集
传送门 如果边不会消失,那么显然可以带权并查集做(然后发现自己不会写带权并查集) 但是每条边有消失时间.这样每一条边产生贡献的时间对应一段区间,故对时间轴建立线段树,将每一条边扔到线段树对应的点上. ...
- hdu 5441 Travel 离线带权并查集
Travel Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5441 De ...
- BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)
BZOJ 差分约束: 我是谁,差分约束是啥,这是哪 太真实了= = 插个广告:这里有差分约束详解. 记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值, ...
- BZOJ 3362 Navigation Nightmare 带权并查集
题目大意:给定一些点之间的位置关系,求两个点之间的曼哈顿距离 此题土豪题.只是POJ也有一道相同的题,能够刷一下 别被题目坑到了,这题不强制在线.把询问离线处理就可以 然后就是带权并查集的问题了.. ...
随机推荐
- 北京Uber优步司机奖励政策(12月13日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 【POJ2182】Lost Cows
[POJ2182]Lost Cows 题面 vjudge 题解 从后往前做 每扫到一个点\(i\)以及比前面小的有\(a[i]\)个数 就是查询当前的第\(a[i]+1\)小 然后查询完将这个数删掉 ...
- 韩国KT软件NB-IOT开发记录V150(2)FOTA差分包生成
1. 生成差分包
- python 水仙花
#简单def narcissus(): for n in range(100, 1000, 1): a, b, c = n//100, (n//10)%10, (n%100)%10 if a ** 3 ...
- Visual Studio 2015 Test Explorer does not show anything
Problem After install Visual Studio 2015 community and NUnit Test Adapter, I cannot find test cases ...
- 用libevent实现的echo服务器及telnet客户端
以下代码在vs 2010编译通过,使用的libevent版本是:libevent-2.0.22,win7环境测试通过. 服务器实现: 1 流程图: 2 代码: // my_telnet.cpp : D ...
- 【转】跨平台移动端开发框架NativeScript 发布正式版本
原文:http://news.cnblogs.com/n/520865/ Nativescript 项目地址:http://www.telerik.com/nativescript “一次编码,处处运 ...
- mapReduce入门教程
什么是MapReduce MapReduce是Google提出的一个软件架构,用于大规模数据集(大于1TB)的并行运算.概念"Map(映射)"和"Reduce(归纳)&q ...
- python读取日志,存入mysql
1.从 http://www.almhuette-raith.at/apache-log/access.log 下载 1万条日志记录,保存为一个文件,读取文件并解析日志,从日志中提取ip, time_ ...
- 条款03 尽可能使用const
一.概述 使用const约束对象:可以获得编译器的帮助(指出相关出错的地方) const与成员函数:const重载.转型.避免代码重复 二.细节 1. 为什么有些函数要返回const对象(看上去没必要 ...