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:从零开始的异世界生活 线段树的更多相关文章

  1. [Essay]看《Re:从零开始的异世界生活》的一些感想

    人生不能重来,但动漫可以. -- 故事背景 <介绍背景> 男主486通过不断重来,而改变了剧情的发展.整个动漫就像RPG游戏一般,只看了一遍没有完全理解,但后来再看萌娘百科才把整个剧情里所 ...

  2. 玲珑oj 1117 线段树+离线+离散化,laz大法

    1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异 ...

  3. 【生活没有希望】hdu1166敌兵布阵 线段树

    线段树水题刷刷,生活没有希望 最近看到代码跟树状数组差不多短的非递归线段树,常数也很小——zkw线段树 于是拿道水题练练手 短到让人身无可恋 ;pos;pos/=) a[pos]+=x;} ,ans= ...

  4. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  5. 洛谷 P2574 XOR的艺术(线段树 区间异或 区间求和)

    To 洛谷.2574 XOR的艺术 题目描述 AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏.在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下 1. 拥有一个伤害串为长度为n的 ...

  6. P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树

    $ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...

  7. 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和

    题意:给出N个数,M个操作.操作有修改和询问两种,每次修改将一个数改成另一个数,每次询问一个区间的所有连续子区间的异或和.n,m<=100000,ai<=1000 题解: 当年(其实也就是 ...

  8. BZOJ 1230 [Usaco2008 Nov]lites 开关灯:线段树异或

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1230 题意: 有n盏灯,一开始全是关着的. 有m次操作(p,a,b).p为0,则将区间[a ...

  9. BZOJ4561:圆的异或并(扫描线+set||splay||线段树)

    在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面    积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑. I ...

随机推荐

  1. zero to one (2)

    kali虚拟机整理 关于kali的虚拟机,我搞崩过很多次,重新安装了很多次,也遇到了很多问题,有一些解决不了的就重新安装,费时费力,要善于用虚拟机. 关于网络配置的问题 关于网络配置,在这里我想主要记 ...

  2. 1072 Gas Station (30)(30 分)

    A gas station has to be built at such a location that the minimum distance between the station and a ...

  3. <十五>UML核心视图动态视图之活动图

    一:动态视图 --->动态视图是描述事物动态行为的. --->需要注意的是:动态视图不能够独立存在,它必需特指一个静态视图活uml元素,说明在静态视图规定的事物结构下它们的动态行为. -- ...

  4. P2042 [NOI2005]维护数列[splay或非旋treap·毒瘤题]

    P2042 [NOI2005]维护数列 数列区间和,最大子列和(必须不为空),支持翻转.修改值.插入删除. 练码力的题,很毒瘤.个人因为太菜了,对splay极其生疏,犯了大量错误,在此记录,望以后一定 ...

  5. ACM学习历程——UVA540 Team Queue(队列,map:Hash)

    Description   Team Queue   Team Queue  Queues and Priority Queues are data structures which are know ...

  6. CodeForces - 204C Little Elephant and Furik and Rubik

    CodeForces - 204C Little Elephant and Furik and Rubik 个人感觉是很好的一道题 这道题乍一看我们无从下手,那我们就先想想怎么打暴力 暴力还不简单?枚 ...

  7. 《TCP/IP详解卷一:协议》 概述

    分层           TCP/IP协议族是一组不同层次上的多个协议的组合.TCP/IP通常被认为是一个四层次协议系统.   链路层(数据链路层或网络接口层):通常包括操作系统中的设备驱动程序和计算 ...

  8. shell中利用ftp 上传文件夹功能

    我们知道ftp 只能用来上传或者下载文件,一次单个或者多个,怎么实现将文件夹的上传和下载呢? 可以利用先在remote ip上建立一个相同的文件夹目录,然后将文件放到各自的目录中去 1.循环遍历出要上 ...

  9. 演讲:对 2000 多亿条数据做一次 group by 需要多久?

    http://2017.qconbeijing.com/presentation/646?utm_source=weibo&utm_medium=infoq&utm_campaign= ...

  10. Oracle 表连接方式(1)---

    Oracle 表之间的连接分为三种: 1. 内连接(自然连接) 2. 外连接 (1)左外连接 (左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不加限制) 3. 自连 ...