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 ...
随机推荐
- liunx让命令窗口显示段路径的方法
平时我们使用linux终端命令行的时候,常常会被一个问题困扰,那就是文件路径过长,有时候甚至超过了一行,这样看起来非常别扭,其实只要两步就可以解决这个问题: 1,修改.bashrc文件(用户根目录下) ...
- P2042 [NOI2005]维护数列[splay或非旋treap·毒瘤题]
P2042 [NOI2005]维护数列 数列区间和,最大子列和(必须不为空),支持翻转.修改值.插入删除. 练码力的题,很毒瘤.个人因为太菜了,对splay极其生疏,犯了大量错误,在此记录,望以后一定 ...
- 「LuoguP1144」 最短路计数(dijkstra
题目描述 给出一个NN个顶点MM条边的无向无权图,顶点编号为1-N1−N.问从顶点11开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 第一行包含22个正整数N,MN,M,为图的顶点数与边 ...
- 「SHOI2002」「LuoguP1291」百事世界杯之旅(UVA10288 Coupons)(期望,输出
题目描述 “……在2002年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字.只要凑齐所有百事球星的名字,就可参加百事世界杯之旅的抽奖活动,获得球星背包,随声听,更克赴日韩观看世界杯.还不赶 ...
- 洛谷P3252 [JLOI2012]树
题目描述 在这个问题中,给定一个值S和一棵树.在树的每个节点有一个正整数,问有多少条路径的节点总和达到S.路径中节点的深度必须是升序的.假设节点1是根节点,根的深度是0,它的儿子节点的深度为1.路径不 ...
- 重学JAVA基础(五):面向对象
1.封装 import java.util.Date; public class Human { protected String name; protected BirthDay birthDay; ...
- TPS与QPS
一.TPS:Transactions Per Second(每秒传输的事物处理个数),即服务器每秒处理的事务数.TPS包括一条消息入和一条消息出,加上一次用户数据库访问.(业务TPS = CAPS × ...
- Html.Partial 和 Html.RenderPartial 、Html.Action 和 Html.RenderAction区别
Html.Partial 和 Html.RenderPartial不需要为视图指定路径和文件扩展名.因为运行时定位部分视图与定位正常视力使用的逻辑相同.RenderPartial不是返回字符串,而是直 ...
- java继承使用的细节问题?
关于java继承的基本概念就不多说了,下面就说说继承使用应该注意的细节问题? 示例 一: package com.bizvane; class Fu{ public Fu() { System.out ...
- 杭电1002_A + B Problem II
这是该题的链接http://acm.hdu.edu.cn/showproblem.php?pid=1002 具体的题的内容就不过多描述了,想必你已经知道了,当我看完这道题后就知道咋写了,可是这道题从开 ...