B -- RE:从零开始的异世界生活 线段树
http://www.ifrog.cc/acm/problem/1117?contest=1016&no=1
其实我是第一次这样用线段树。
首先把所有出现过的数字全部离散化。那么数字就是从[1, 100000]了。
把他们看成一个个独立的节点。每次插入一个数字,就在那个位置加1.
那么线段树维护区间总和,想知道小于x的数字有多少个,直接区间查询[1, x - 1]即可。
如果把小于x的数,变成x,相当于把[1, x - 1]中出现了多少个数字,贡献 add 到 x这个位置,然后把[1, x - 1]清0即可。
查询第k小,可以二分然后判断。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
#define lson L, mid, cur << 1
#define rson mid + 1, R, cur << 1 | 1
const int maxn = + ;
struct Node {
int op, val;
}query[maxn];
vector<int>vc;
set<int>ss;
int sum[maxn << ];
int add[maxn << ];
void pushUp(int cur) {
sum[cur] = sum[cur << ] + sum[cur << | ];
}
void pushDown(int cur, int total) {
if (add[cur] != -inf) {
add[cur << ] = add[cur];
add[cur << | ] = add[cur];
sum[cur << ] = sum[cur << | ] = ;
add[cur] = -inf;
}
}
void upDate(int be, int en, int val, int L, int R, int cur) {
if (be > en) return;
if (L >= be && R <= en) {
add[cur] = val;
sum[cur] = val;
return;
}
pushDown(cur, R - L + );
int mid = (L + R) >> ;
if (be <= mid) upDate(be, en, val, lson);
if (en > mid) upDate(be, en, val, rson);
pushUp(cur);
}
int ask(int be, int en, int L, int R, int cur) {
if (en < be) return ;
if (L >= be && R <= en) return sum[cur];
pushDown(cur, R - L + );
int ans = , mid = (L + R) >> ;
if (be <= mid) ans += ask(be, en, lson);
if (en > mid) ans += ask(be, en, rson);
return ans;
}
#define root 1, n, 1
int n;
int slove(int x) { //要大于多少个number
int be = , en = n;
while (be <= en) {
int mid = (be + en) >> ;
int res = ask(, mid, root);
if (res >= x) en = mid - ;
else be = mid + ;
}
return vc[be];
}
void work() {
int en = maxn << ;
for (int i = ; i <= en - ; ++i) add[i] = -inf;
vc.push_back(-inf);
int q;
scanf("%d", &q);
for (int i = ; i <= q; ++i) {
scanf("%d%d", &query[i].op, &query[i].val);
ss.insert(query[i].val);
}
for (set<int> :: iterator it = ss.begin(); it != ss.end(); ++it) {
vc.push_back(*it);
}
n = vc.size();
n--;
int nowHas = ;
for (int i = ; i <= q; ++i) {
int op = query[i].op, val = query[i].val;
int pos = lower_bound(vc.begin(), vc.end(), val) - vc.begin();
if (op == ) {
nowHas++;
int has = ask(pos, pos, root);
upDate(pos, pos, has + , root);
} else if (op == ) {
int res = ask(, pos, root);
upDate(pos, pos, res, root);
upDate(, pos - , , root);
} else if (op == ) {
int res = ask(, n, root) - ask(, pos, root);
upDate(pos, pos, res, root);
upDate(pos + , n, , root);
} else if (op == ) {
printf("%d\n", slove(val));
} else if (op == ) {
int res = ask(, pos - , root);
printf("%d\n", res);
}
}
// printf("*****************\n");
// printf("%d\n", ask(1, 3, root));
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}
B -- RE:从零开始的异世界生活 线段树的更多相关文章
- [Essay]看《Re:从零开始的异世界生活》的一些感想
人生不能重来,但动漫可以. -- 故事背景 <介绍背景> 男主486通过不断重来,而改变了剧情的发展.整个动漫就像RPG游戏一般,只看了一遍没有完全理解,但后来再看萌娘百科才把整个剧情里所 ...
- 玲珑oj 1117 线段树+离线+离散化,laz大法
1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异 ...
- 【生活没有希望】hdu1166敌兵布阵 线段树
线段树水题刷刷,生活没有希望 最近看到代码跟树状数组差不多短的非递归线段树,常数也很小——zkw线段树 于是拿道水题练练手 短到让人身无可恋 ;pos;pos/=) a[pos]+=x;} ,ans= ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- 洛谷 P2574 XOR的艺术(线段树 区间异或 区间求和)
To 洛谷.2574 XOR的艺术 题目描述 AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏.在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下 1. 拥有一个伤害串为长度为n的 ...
- P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树
$ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...
- 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和
题意:给出N个数,M个操作.操作有修改和询问两种,每次修改将一个数改成另一个数,每次询问一个区间的所有连续子区间的异或和.n,m<=100000,ai<=1000 题解: 当年(其实也就是 ...
- BZOJ 1230 [Usaco2008 Nov]lites 开关灯:线段树异或
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1230 题意: 有n盏灯,一开始全是关着的. 有m次操作(p,a,b).p为0,则将区间[a ...
- BZOJ4561:圆的异或并(扫描线+set||splay||线段树)
在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面 积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑. I ...
随机推荐
- hdu-5784 How Many Triangles(计算几何+极角排序)
题目链接: How Many Triangles Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- zero to one (4)
复盘--天下武功唯快不破 There is no martial art is indefectible, while the fastest speed is the only way for lo ...
- Jquery通过ajax请求NodeJS返回json数据
最近看了NodeJS相关的,在网上查了下结合AJAX的应用,感觉应用前景还是不错的.为什么用这个组合呢? 1.NodeJS不需要安装,拷贝过去就可以使用,而环境变量可以只配置在当前cmd窗口,运行方便 ...
- WPF中Visible设为Collapse时,VisualTreeHelper.GetChildrenCount为0
今天遇到一个奇怪的问题, 在给一个控件内的子元素绑定事件时,失败. 发现原因是,这个控件初始化时Visible="Collapse",这时控件内的可视树就没有生成.导致绑定事件失败 ...
- CentOS下编写shell脚本来监控MySQL主从复制的教程
这篇文章主要介绍了在CentOS系统下编写shell脚本来监控主从复制的教程,文中举了两个发现故障后再次执行复制命令的例子,需要的朋友可以参考下 目的:定时监控MySQL主从数据库是否同步,如果不同步 ...
- MangoDB篇章(1)
关系型数据库遵循ACID规则 事务(transaction)4个特性:原子性(A).一致性(C).独立性(I).持久性(D) : 分布式系统(distributed system): 由多台计算机和通 ...
- MFC获取数据的方式
假设输入框ID是:ID_NUMBER1,ID_NUMBER2,ID_NUMBER3. 获取数据的方式是: int number1,number2,number3; number1 = GetDlgIt ...
- linux cpu内存利用率获取
有了这么好的工具,我们还需要自己造轮子么? 两种情况,如果有复杂的监控需求,而且愿意花时间学习,我们可以使用nmon:但如果监控需求特殊比如说还要监控单个进程的情况,这时候就需要自己动手实现了.自己动 ...
- 关于java基础中,接口里面父类的对象指向子类的引用
父类的引用指向子类的对象,它只能看的到父类的那些方法~ 子类自身的方法看不到-- ······························· 如: interface Singer { //定义了 ...
- eclipse修改workspace
Eclipse是一款很强的Java IDE,我们在开始的时候,往往设定了默认的workspace,当用久在之后,我们可能要去更改一下workspace的位置,但是在启动的时候已经不会显示更改了.下面有 ...