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 ...
随机推荐
- WebService生成XML文档时出错。不应是类型XXXX。使用XmlInclude或SoapInclude属性静态指定非已知的类型。
情况是SingleRoom和DoubleRoom是Room类的子类.在WebService中有一个方法是返回Room类. public Room Get(int roomId) { return Ro ...
- HBase的replication原理及部署
一.hbase replication原理 hbase 的复制方式是 master-push 方式,即主集群推的方式,主要是因为每个rs都有自己的WAL. 一个master集群可以复制给多个从集群,复 ...
- 8)django-示例(url传递参数)
url传递参数有两种,一个是通过普通分组方式,一个是通过带命名分组方式 1.传递方式 1)普通分组方式,传递参数顺序是严格的.如下例子 url(r'^detail-(\d+)-(\d+).html', ...
- 洛谷P4827 [国家集训队] Crash 的文明世界 [斯特林数,组合数,DP]
传送门 思路 又见到这个\(k\)次方啦!按照套路,我们将它搞成斯特林数: \[ ans_x=\sum_{i=0}^k i!S(k,i)\sum_y {dis(x,y) \choose i} \] 前 ...
- linux命令tar压缩解压
tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...
- 注册InstallShield
安装InstallShield 下载installshield limitededition版本,这个版本是免费的 注册 安装打开后会给一个网址要求进行注册 其中,国籍是必填项但是下拉菜单中没有内容, ...
- PID控制器开发笔记之四:梯形积分PID控制器的实现
从微积分的基本原理看,积分的实现是在无限细分的情况下进行的矩形加和计算.但是在离散状态下,时间间隔已经足够大,矩形积分在某些时候显得精度要低了一些,于是梯形积分被提出来以提升积分精度. 1.梯形积分基 ...
- Confluence 6 中进行用户管理的优化配置和限制的基本建议
避免跨目录的多个用户名:如果你连接了超过一个的目录服务器,我们建议你需要确定你的用户名在目录服务器中是唯一的.例如:我们不建议你定义一个用户同时在'Directory1' 和 'Directory2' ...
- 编辑后保留原URl搜索条件
首先需要知道的一个知识点: 1.request.GET是一个QueryDict类型的,要想取出?后面的结构就用request.GET.urlencode() 2.request.GET默认是不可修改的 ...
- ubuntu MySQL的安装
https://i.cnblogs.com/EditPosts.aspx?opt=1 https://juejin.im/entry/5adb5deff265da0b9d77cb3b MySQL Co ...