这题搞了我一天啊。。。拍不出错原来是因为极限数据就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 棘手的操作(离线+线段树+带权并查集)的更多相关文章

  1. 2333: [SCOI2011]棘手的操作[离线线段树]

    2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2325  Solved: 909[Submit][Stat ...

  2. BZOJ 1202 狡猾的商人 差分约束or带权并查集

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1202 题目大意: 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的 ...

  3. BZOJ 3376 [Usaco2004 Open]Cube Stacking 方块游戏(带权并查集)

    题解 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #in ...

  4. 【BZOJ4025】二分图(线段树分治,并查集)

    [BZOJ4025]二分图(线段树分治,并查集) 题面 BZOJ 题解 是一个二分图,等价于不存在奇环. 那么直接线段树分治,用并查集维护到达根节点的距离,只计算就好了. #include<io ...

  5. 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)

    [CF938G]Shortest Path Queries(线段树分治,并查集,线性基) 题面 CF 洛谷 题解 吼题啊. 对于每个边,我们用一个\(map\)维护它出现的时间, 发现询问单点,边的出 ...

  6. BZOJ4025 二分图 线段树分治、带权并查集

    传送门 如果边不会消失,那么显然可以带权并查集做(然后发现自己不会写带权并查集) 但是每条边有消失时间.这样每一条边产生贡献的时间对应一段区间,故对时间轴建立线段树,将每一条边扔到线段树对应的点上. ...

  7. hdu 5441 Travel 离线带权并查集

    Travel Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5441 De ...

  8. BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)

    BZOJ 差分约束: 我是谁,差分约束是啥,这是哪 太真实了= = 插个广告:这里有差分约束详解. 记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值, ...

  9. BZOJ 3362 Navigation Nightmare 带权并查集

    题目大意:给定一些点之间的位置关系,求两个点之间的曼哈顿距离 此题土豪题.只是POJ也有一道相同的题,能够刷一下 别被题目坑到了,这题不强制在线.把询问离线处理就可以 然后就是带权并查集的问题了.. ...

随机推荐

  1. 如何在同一个Excel里,对两个很相似的工作簿比对出不同之处

    如何在同一个Excel里,对两个很相似的工作簿比对出不同之处

  2. Java设计模式(23)——行为模式之访问者模式(Visitor)

    一.概述 概念 作用于某个对象群中各个对象的操作.它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作. 引入 试想这样一个场景,在一个Collection中放入了一大堆的各种对象的引用 ...

  3. 苏州Uber优步司机奖励政策(3月28日~3月30日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. journalctl 日志查看方法

    1  概述 日志管理工具journalctl是centos7上专有的日志管理工具,该工具是从message这个文件里读取信息.Systemd统一管理所有Unit的启动日志.带来的好处就是,可以只用jo ...

  5. “地表最贵iPhone”到货,iPhone XS 系列手机等你来测!

    WeTest 导读 9月13日,苹果正式发布了全新的 iPhone XS 系列智能手机,备受瞩目的iPhone家族新成员具体又是怎样的呢?   关于iPhone XS系列手机的那些新亮点   大屏.双 ...

  6. VIN码识别(车架号识别)在二手车交易中的应用

    最新数据统计,2015年,中国卖出2110万辆新车,相比之下,美国卖出去了1740辆新车.然而,如果算上二手车,美国的汽车市场销量将扩展到4000多辆,而中国的乘用车才不到3000万辆. 销售总额上, ...

  7. OSG-获取OSG的源代码和第三方库并编译

    获取OSG的源代码有很多方式. 这里说下其中的两个地方,第一就是中国的OSG网站http://www.osgchina.org/,这个网站目前应该是由中国西安恒歌科技维护,同时,西安恒歌科技也是一家已 ...

  8. 接口测试工具postman(五)批量执行测试用例

    1.准备好测试用例及相关数据 2.点击Run按钮 3.选择运行collection或者folder 4.运行完成

  9. android自动化のadb常用命令(不定期更新)

    1. adb devices 执行结果是adb为每一个设备输出以下状态信息:序列号(serialNumber) — 由adb创建的使用控制台端口号的用于唯一标识一个模拟器或手机设备的字符串,格式是 & ...

  10. 利用nohup后台运行jar文件包程序

    Linux 运行jar包命令如下: 方式一: java -jar XXX.jar特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 j ...