【Foreign】数据结构C [线段树]
数据结构C
Time Limit: 20 Sec Memory Limit: 512 MB
Description

Input

Output

Sample Input

Sample Output

HINT

Solution
首先,D操作为删除操作显然不可做,又发现这道题可以离线处理,那么我们考虑倒着来,维护加入操作。
那么这时候,D操作就变为了合并操作,那么这时候我们只需要维护一个:可以支持单点修改、查询第 k 大、信息可合并的数据结构即可。
显然构建若干棵权值线段树即可!对于每个联通块维护一棵线段树,用并查集判断两点是否在一个块内。
这时候,D操作显然判断一下两点是否在一个联通块内,不在则合并两棵线段树;Q操作就是查询第 k 大,在树上二分即可;C操作就是原来值个数-1,新加入值个数+1。
就简单地解决了这题啦!(本质上就是BZOJ1926弱化 + BZOJ1015 QWQ)
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std; const int ONE = ;
const int INF = 2e6;
const int Base = 1e6; int n, m;
int opt, x, val;
int Val[];
char s[]; int Ans[], ans_num = ; int fat[]; int Num = , del[];
struct power {int opt, x, val;} oper[ONE];
struct point {int x, y;} a[];
int total = ;
struct seg
{
int root;
int left, right;
int val;
}Node[ONE * ]; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int Find(int x)
{
if(fat[x] == x) return x;
return fat[x] = Find(fat[x]);
} void Un(int x, int y)
{
int f1 = Find(x), f2 = Find(y);
if(f1 != f2) fat[f1] = f2;
} void Update(int &i, int l, int r, int Val, int opt) //pos = Val , + opt
{
if(!i) i = ++total; Node[i].val = Node[i].val + opt; if(l == r) return;
int mid = l + r >> ; if(Val <= mid) Update(Node[i].left, l, mid, Val, opt);
else Update(Node[i].right, mid + , r, Val, opt); } int Merge(int y, int x) //y merge to x
{
if(x == || y == ) return x + y; Node[x].val += Node[y].val;
Node[x].left = Merge(Node[x].left, Node[y].left);
Node[x].right = Merge(Node[x].right, Node[y].right); return x;
} int Query(int i, int l, int r, int k) //k da
{
if(l == r) return l;
int mid = l + r >> , Val = Node[ Node[i].right ].val; if(k > Val)
return Query(Node[i].left, l, mid, k - Val);
else
return Query(Node[i].right, mid + , r, k);
} void Deal_first()
{
for(int i = ; i <= n; i++)
fat[i] = i, Node[i].root = ++total;
for(int i = ; i <= m; i++)
if(del[i] != ) Un(a[i].x, a[i].y);
for(int i = ; i <= n; i++)
Update(Node[Find(i)].root, , INF, Val[i], );
} void Deal_add(int x, int y)
{
x = Find(x), y = Find(y);
if(x == y) return;
Merge(Node[x].root, Node[y].root);
fat[x] = y;
} void Deal_query(int root, int k)
{
root = Find(root);
if(Node[root].val < k) {Ans[++ans_num] = + Base; return;}
Ans[++ans_num] = Query(Node[root].root, , INF, k);
} void Deal_change(int x, int y) //x is point, y is need val
{
int root = Find(x);
Update(Node[root].root, , INF, Val[x], -);
Update(Node[root].root, , INF, y, );
Val[x] = y;
} int main()
{
n = get(); m = get(); for(int i = ; i <= n; i++) Val[i] = get() + Base;
for(int i = ; i <= m; i++)
a[i].x = get(), a[i].y = get();
for(;;)
{
scanf("%s", s);
if(s[] == 'E') break;
if(s[] == 'D')
x = get(), del[x] = , oper[++Num] = (power){, x, };
if(s[] == 'Q')
x = get(), val = get(), oper[++Num] = (power){, x, val};
if(s[] == 'C')
x = get(), val = get(), oper[++Num] = (power){, x, Val[x]}, Val[x] = val + Base;
} Deal_first();
for(int i = Num; i >= ; i--)
{
if(oper[i].opt == ) Deal_add(a[ oper[i].x ].x, a[ oper[i].x ].y);
if(oper[i].opt == ) Deal_query(oper[i].x, oper[i].val);
if(oper[i].opt == ) Deal_change(oper[i].x, oper[i].val);
} for(int i = ans_num; i >= ; i--)
printf("%d\n", Ans[i] - Base);
}
- [提交][状态][讨论]
【Foreign】数据结构C [线段树]的更多相关文章
- 数据结构-PHP 线段树的实现
转: 数据结构-PHP 线段树的实现 1.线段树介绍 线段树是基于区间的统计查询,线段树是一种 二叉搜索树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点.使用线段树可以快速的查 ...
- 【数据结构】线段树(Segment Tree)
假设我们现在拿到了一个非常大的数组,对于这个数组里面的数字要反复不断地做两个操作. 1.(query)随机在这个数组中选一个区间,求出这个区间所有数的和. 2.(update)不断地随机修改这个数组中 ...
- 数据结构1 线段树查询一个区间的O(log N) 复杂度的证明
线段树属于二叉树, 其核心特征就是支持区间加法,这样就可以把任意待查询的区间$[L, R]$分解到线段树的节点上去,再把这些节点的信息合并起来从而得到区间$[L,R]$的信息. 下面证明在线段树上查询 ...
- 数据结构(线段树):Educational Codeforces Round 6 620E. New Year Tree
E. New Year Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard in ...
- 数据结构(线段树):BZOJ 1568 [JSOI2008]Blue Mary开公司
1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 602 Solved: 214[Submit ...
- 牛客练习赛28 B数据结构(线段树)
链接:https://www.nowcoder.com/acm/contest/200/B来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...
- 2018.10.12 NOIP模拟 数据结构(线段树)
传送门 sb线段树题居然还卡常. 修改操作直接更新区间最小值和区间标记下传即可. 询问加起来最多5e65e65e6个数. 因此直接询问5e65e65e6次最小值就行了. 代码
- 【uoj#228】基础数据结构练习题 线段树+均摊分析
题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有三种:区间加.区间开根.区间求和. $n,m,a_i\le 100000$ . 题解 线段树+均摊分析 对于原来的两个数 $a$ ...
- 【Foreign】Weed [线段树]
Weed Time Limit: 20 Sec Memory Limit: 512 MB Description 从前有个栈,一开始是空的. 你写下了 m 个操作,每个操作形如 k v : 若 k ...
随机推荐
- 20172333 2017-2018-2 《Java程序设计》第7周学习总结
20172333 2017-2018-2 <Java程序设计>第7周学习总结 教材学习内容 1.继承是创建新类的快捷方式之一,继承可以使用父类的所有方法及对象. 2.继承具有单向性,父类不 ...
- Python 服务器端表单验证插件
Python格式验证库 Cerberus 作者 MrStranger 关注 2016.08.02 14:44 字数 2140 阅读 79评论 0喜欢 1 Cerberus是一个验证Python对象.M ...
- 《学习OpenCV》课后习题解答1
题目:(P104) 下面这个练习是帮助掌握矩阵类型.创造一个三通道二维矩阵,字节类型,大小为100*100,并设置所有数值为0. a.在矩阵中使用cvCircle( CvArr* img, CvPoi ...
- YaoLingJump开发者日志(八)V1.1版本完成
跳跃吧瑶玲下载连接 官网下载(网站服务器不支持10M以上的文件上传-_-||) 百度网盘下载 介绍 忙里偷闲,把之前的工作整理了一下完成V1.1版本,下面是更新! (1)去掉了积分榜. (2)增加 ...
- Jenkins系列-Jenkins用户权限和角色配置
由于jenkins默认的权限管理体系不支持用户组或角色的配置,因此需要安装第三发插件来支持角色的配置,这边将使用Role Strategy Plugin,介绍页面:https://wiki.jenki ...
- 抽象类 C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- hibernate.cfg.xml的详细解释
<!--标准的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的编码方式--> < ...
- js 复制到剪贴板 兼容还得自己想办法
clipboard.js https://github.com/zenorocha/clipboard.js/ 主要问题还是ie8, 可以使用ie 特有的方法 if (window.clipboard ...
- Go语言【第五篇】:Go条件语句
Go语言条件 条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为true来决定是否执行指定语句,并在条件为false的情况再执行另外的语句.下图展示了程序语言中条件语句的结构: Go语言提 ...
- Springboot2.x+shiro+redis(Lettuce)整合填坑
主要记录关键和有坑的地方 前提: 1.SpringBoot+shiro已经集成完毕,如果没有集成,先查阅之前的Springboot2.0 集成shiro权限管理 2.redis已经安装完成 3.red ...