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 ...
随机推荐
- zabbix添加对haproxy的监控
zabbix添加对haproxy的监控 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy本身提供一个web页面 ...
- T-SQL 数值函数
MS SQL Server数字函数可以应用于数值数据,并返回数值数据. 下面是带有示例的数值函数列表. ABS() 输出给定值的绝对值. 例 以下查询将输出-22的绝对值:22. Select ABS ...
- codecs and formats of digital media
A codec is a device or software that is used to compress or decompress a digital media file, such as ...
- 关于Dubbo和Spring异步注解@Async的冲突
项目中难免会有异步处理的需求,像异步记录日志啦,异步发送邮件啦,而Dubbo又是现在主流的分布式框架,所有异步+Dubbo的组合是再所难免的 但博主是实践中发现Dubbo的服务并不能很好的跟Sprin ...
- dubbo常用网址
https://dubbo.gitbooks.io/dubbo-user-book/content/references/protocol/dubbo.html http://dubbo.apache ...
- Spring与Quartz实现定期任务
<!-- 任务调度测试实现一 : 自定义的任务对象com.bocloud.equipment.test.ExampleJob 必须继承QuartzJobBean类,实现抽象方法executeIn ...
- python中的各种锁
一.全局解释器锁(GIL) 1.什么是全局解释器锁 在同一个进程中只要有一个线程获取了全局解释器(cpu)的使用权限,那么其他的线程就必须等待该线程的全局解释器(cpu)使 用权消失后才能使用全局解释 ...
- nginx+ssl 服务器 双向认证
项目后台服务器采用nginx+tomcat 负载均衡架构 不久 访问协议有http升级为https 对服务器认证采用沃通的ssl证书 nginx ssl证书安装 参照沃通官方文档 他们有技术支持沟通 ...
- python 面向对象编程(高级篇)
飞机票 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对 ...
- js调用Webservice接口案例
第一步:新建Webservice接口 主文件方法 using System;using System.Collections.Generic;using System.Web;using System ...