Codeforces 1139F Dish Shopping 树状数组套平衡树 || 平衡树
将每个物品拆成p 和 s 再加上人排序。 然后问题就变成了, 对于一个线段(L - R),
问有多少个(li, ri)满足 L >= li && R >= ri, 这个东西可以直接树状数组套平衡树维护。
但是这个题目有个特殊性,因为排好序之后不会存在 li > L && ri > R的点, 所以可以直接
用平衡树, 或者线段树去维护这个东西。
平板电视
#include<bits/stdc++.h>
#include <bits/extc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std;
using namespace __gnu_pbds; const int N = 1e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ;
const double eps = 1e-;
const double PI = acos(-); int n, m, tot, ans[N * ], hs[N], cnt;
int p[N], s[N], b[N], inc[N], pref[N]; struct event {
int p, b, id, op, rp;
bool operator < (const event& rhs) const {
if(p == rhs.p) return op < rhs.op;
else return p < rhs.p;
}
} e[N * ]; template <class T>
using Tree = tree<T, null_type, std::less<T>, rb_tree_tag,tree_order_statistics_node_update>; struct Bit {
Tree<PII> T[N];
void add(int x, PII v) {
for(int i = x; i <= cnt; i += i & -i)
T[i].insert(v);
}
void del(int x, PII v) {
for(int i = x; i <= cnt; i += i & -i)
T[i].erase(v);
}
int sum(int x, int R) {
int ans = ;
for(int i = x; i; i -= i & -i)
ans += T[i].order_of_key(mk(R, INT_MAX));
return ans;
}
} bit; int getPos(int x) {
return upper_bound(hs + , hs + + cnt, x) - hs - ;
} int main() {
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) scanf("%d", &p[i]);
for(int i = ; i <= n; i++) scanf("%d", &s[i]);
for(int i = ; i <= n; i++) scanf("%d", &b[i]);
for(int i = ; i <= n; i++) {
e[++tot] = event{p[i], b[i], i, , p[i]};
e[++tot] = event{s[i], b[i], i, , p[i]};
hs[++cnt] = p[i] - b[i];
}
for(int i = ; i <= m; i++) scanf("%d", &inc[i]);
for(int i = ; i <= m; i++) scanf("%d", &pref[i]);
for(int i = ; i <= m; i++) e[++tot] = event{inc[i], pref[i], n + i, , }; sort(hs + , hs + + cnt);
cnt = unique(hs + , hs + + cnt) - hs - ; sort(e + , e + + tot);
for(int i = ; i <= tot; i++) {
int p = e[i].p, b = e[i].b, rp = e[i].rp;
if(e[i].op == ) {
bit.add(getPos(rp - b), mk(rp + b, e[i].id));
} else if(e[i].op == ) {
ans[e[i].id] = bit.sum(getPos(p - b), p + b);
} else {
bit.del(getPos(rp - b), mk(rp + b, e[i].id));
}
}
for(int i = n + ; i <= n + m; i++) printf("%d ", ans[i]);
puts("");
return ;
} /*
*/
treap, 为啥我的treap好慢啊啊啊。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 1e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ;
const double eps = 1e-;
const double PI = acos(-); mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int n, m, tot, ans[N * ], hs[N], cnt;
int p[N], s[N], b[N], inc[N], pref[N]; struct event {
int p, b, id, op, rp;
bool operator < (const event& rhs) const {
if(p == rhs.p) return op < rhs.op;
else return p < rhs.p;
}
} e[N * ]; struct node {
node* ch[];
int key, fix, sz, cnt;
void update() {
sz = ch[]->sz + ch[]->sz + cnt;
}
} base[N * ]; typedef node* P_node;
P_node len = base; struct Treap {
node nil;
P_node root, null;
Treap() {
root = null = &nil;
null->key = null->fix = inf;
null->sz = null->cnt = ;
null->ch[] = null->ch[] = null;
}
P_node newnode(int tkey) {
len->key = tkey;
len->fix = rng();
len->ch[] = len->ch[] = null;
len->sz = len->cnt = ;
return len++;
}
void rot(P_node &p, int d) {
P_node k = p->ch[d ^ ];
p->ch[d ^ ] = k->ch[d];
k->ch[d] = p;
p->update();
k->update();
p = k;
}
void _Insert(P_node &p, int tkey) {
if(p == null) {
p = newnode(tkey);
} else if(p->key == tkey) {
p->cnt++;
} else {
int d = tkey > p->key;
_Insert(p->ch[d], tkey);
if(p->ch[d]->fix > p->fix) {
rot(p, d ^ );
}
}
p->update();
} void _Delete(P_node &p, int tkey) {
if(p == null) return;
if(p->key == tkey) {
if(p->cnt > ) p->cnt--;
else if(p->ch[] == null) p = p->ch[];
else if(p->ch[] == null) p = p->ch[];
else {
int d = p->ch[]->fix > p->ch[]->fix;
rot(p, d);
_Delete(p->ch[d], tkey);
}
} else {
_Delete(p->ch[tkey > p->key], tkey);
}
p->update();
}
int _Kth(P_node p, int k) {
if(p == null || k < || k > p->sz) return ;
if(k < p->ch[]->sz + ) return _Kth(p->ch[], k);
if(k > p->ch[]->sz + p->cnt) return _Kth(p->ch[], k - p->ch[]->sz - p->cnt);
return p->key;
}
int _Rank(P_node p, int tkey, int res) {
if(p == null) return -;
if(p->key == tkey) return p->ch[]->sz + res + ;
if(tkey < p->key) return _Rank(p->ch[], tkey, res);
return _Rank(p->ch[], tkey, res + p->ch[]->sz + p->cnt);
}
int _Pred(P_node p, int tkey){
if(p == null) return -inf;
if(tkey <= p->key) return _Pred(p->ch[], tkey);
return max(p->key, _Pred(p->ch[], tkey));
}
int _Succ(P_node p, int tkey){
if(p == null) return inf;
if(tkey >= p->key) return _Succ(p->ch[], tkey);
return min(p->key, _Succ(p->ch[], tkey));
}
int _Query(P_node p, int tkey) {
if(p == null) return ;
if(p->key > tkey) return _Query(p->ch[], tkey);
else if(p->key < tkey) return p->cnt + p->ch[]->sz + _Query(p->ch[], tkey);
else return p->cnt + p->ch[]->sz;
}
void Insert(int tkey){ _Insert(root,tkey); }
void Delete(int tkey){ _Delete(root,tkey); }
int Kth(int k){ return _Kth(root,k); }
int Rank(int tkey){ return _Rank(root,tkey,); }
int Pred(int tkey){ return _Pred(root,tkey); }
int Succ(int tkey){ return _Succ(root,tkey); }
int Query(int tkey){ return _Query(root, tkey); }
}tp; struct Bit {
Treap T[N];
void add(int x, int v) {
for(int i = x; i <= cnt; i += i & -i)
T[i].Insert(v);
}
void del(int x, int v) {
for(int i = x; i <= cnt; i += i & -i)
T[i].Delete(v);
}
int sum(int x, int R) {
int ans = ;
for(int i = x; i; i -= i & -i)
ans += T[i].Query(R);
return ans;
}
} bit; int getPos(int x) {
return upper_bound(hs + , hs + + cnt, x) - hs - ;
} int main() {
srand(time(NULL));
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) scanf("%d", &p[i]);
for(int i = ; i <= n; i++) scanf("%d", &s[i]);
for(int i = ; i <= n; i++) scanf("%d", &b[i]);
for(int i = ; i <= n; i++) {
e[++tot] = event{p[i], b[i], i, , p[i]};
e[++tot] = event{s[i], b[i], i, , p[i]};
hs[++cnt] = p[i] - b[i];
}
for(int i = ; i <= m; i++) scanf("%d", &inc[i]);
for(int i = ; i <= m; i++) scanf("%d", &pref[i]);
for(int i = ; i <= m; i++) e[++tot] = event{inc[i], pref[i], n + i, , }; sort(hs + , hs + + cnt);
cnt = unique(hs + , hs + + cnt) - hs - ; sort(e + , e + + tot);
for(int i = ; i <= tot; i++) {
int p = e[i].p, b = e[i].b, rp = e[i].rp;
if(e[i].op == ) {
bit.add(getPos(rp - b), rp + b);
} else if(e[i].op == ) {
ans[e[i].id] = bit.sum(getPos(p - b), p + b);
} else {
bit.del(getPos(rp - b), rp + b);
}
}
for(int i = n + ; i <= n + m; i++) printf("%d ", ans[i]);
puts("");
return ;
} /*
*/
Codeforces 1139F Dish Shopping 树状数组套平衡树 || 平衡树的更多相关文章
- codeforces#1139F. Dish Shopping (离散化数组数组+ 扫描线)
膜拜大佬:https://blog.csdn.net/xyz32768/article/details/88831233 题目链接: http://codeforces.com/contest/113 ...
- Codeforces 605D - Board Game(树状数组套 set)
Codeforces 题目传送门 & 洛谷题目传送门 事实上是一道非常容易的题 很容易想到如果 \(c_i\geq a_j\) 且 \(d_i\geq b_j\) 就连一条 \(i\to j\ ...
- Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)
E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- 【BZOJ-1452】Count 树状数组 套 树状数组
1452: [JSOI2009]Count Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1769 Solved: 1059[Submit][Stat ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...
- BZOJ1901 - Dynamic Rankings(树状数组套主席树)
题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t 要求你把第i个数修改为t 题解 动态的区间第k ...
随机推荐
- web@前端--html,css,javascript简介、第一个页面(常用标签简介)
1.什么是标签#1.在HTML中规定标签使用英文的的尖括号即`<`和`>`包起来,如`<html>`.`<head>`.`<body>`都是标签,#2. ...
- how to get address of member function
see:http://www.cplusplus.com/forum/general/136410/ & http://stackoverflow.com/questions/8121320/ ...
- 嵌入式程序设计中C/C++代码的优化
虽然使软件正确是一个工程合乎逻辑的最后一个步骤,但是在嵌入式的系统开发中,情况并不总是这样的.出于对低价产品的需求,硬件的设计者需要提供刚好足够的存储器和完成工作的处理能力.所以在嵌入式软件设计的最后 ...
- Linux i2c 读写程序
/* This software uses a BSD license. Copyright (c) 2010, Sean Cross / chumby industriesAll rights re ...
- 百度echarts插件x轴坐标显示不全决解方法
X轴显示不全: xAxis.axisLabel.interval number, Function [ default: 'auto' ] 坐标轴刻度标签的显示间隔,在类目轴中有效. 默认会采用标签不 ...
- word在线预览编辑器
https://blog.csdn.net/liuli283/article/details/73776685 https://blog.csdn.net/mxljiayou/article/deta ...
- Modbus库开发笔记之四:Modbus TCP Client开发
这一次我们封装Modbus TCP Client应用.同样的我们也不是做具体的应用,而是实现TCP客户端的基本功能.我们将TCP客户端的功能封装为函数,以便在开发具体应用时调用. 对于TCP客户端我们 ...
- Confluence 6 管理协同编辑 - 审计的考虑
我们知道一些客户对审计是主要考虑的方面.我们不能保证在协同编辑的时候具有审计,审查功能.所有页面的修改当前附加到用户发布页面的属性中而不是用户的特定修改. 如果这个对你来说是一个问题的话,我们建议你在 ...
- Confluence 6 代理和 HTTPS 详细配置指南链接
详细配置指南 更多有关连接器示例,我们提供了一些按步骤配置的指南来帮助你启用 HTTPS 并正确配置你的代理. HTTPS: Running Confluence Over SSL or HTTPS ...
- Confluence 6 配置默认语言界面
Confluence 6 配置默认语言使用的界面. https://www.cwiki.us/display/CONFLUENCEWIKI/Choosing+a+Default+Language