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. C/C++的四大内存分区和常量的存储位置

    原文:https://blog.csdn.net/k346k346/article/details/45592329 正确的理解C/C++程序的内存分区,是合格程序猿的基本要求. 网络上流形两大版本内 ...

  2. 天池历届大赛答辩PPT及视频

    1.阿里移动推荐算法: 答辩视频:https://space.dingtalk.com/c/gQHOEnXdXw 2.资金流入流出预测: 答辩视频:https://space.dingtalk.com ...

  3. python 之深浅拷贝

    浅拷贝: 深拷贝:

  4. 使用google浏览器模拟手机终端的方法

    谷歌Chrome浏览器,可以很方便地用来当移动终端模拟器.在Windows的[开始]-->[运行]中输入以下命令,启动谷歌浏览器,即可模拟相应手机的浏览器去访问3G手机网页,前提:将先前开启的谷 ...

  5. CodeForces - 767A Snacktower

    题目大意 一个数可以被输出当且仅当所有比它大的数都已经输出.输入一个1~n的排列,求每次输出的输出序列. 题解 直接用堆模拟 #include <queue> #include <c ...

  6. dubbo的扩展点重构

    可扩展设计是框架要重点考虑的设计,因为它直接影响到框架的稳定性和功能的扩展,Dubbo扩展点重构.它在扩展性设计上踩过的坑,值得框架设计者借鉴学习. 第一步,微核心,插件式,平等对待第三方 即然要扩展 ...

  7. ogg概叙、架构、进程

    一. OGG 概述 OGG 全称Oracle Golden Gate. 历史: Golden Gate公司于1995年成立于美国加州旧金山,它的名称源自旧金山闻名于世的金门大桥.两位创始人Eric F ...

  8. APNS消息推送实现

    转自:http://blog.csdn.net/biaobiaoqi/article/details/8058503 一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1 ...

  9. VR虚拟现实眼镜那些事

    今天是2014.3.20,笔者从oculus官网订了DK2(第二代开发版) 评测视频http://v.youku.com/v_show/id_XNjg3NTUzOTk2.html 想想从哪说起呢... ...

  10. scores

    题意: m维偏序问题. 解法: 考虑对每一维按照每一个元素在这一维的数值分块,对于每一个块维护一个大小为 n 的bitset,表示前缀/后缀满足条件的元素集合. 对于每一个询问,我们可以枚举找到相应的 ...