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 树状数组套平衡树 || 平衡树的更多相关文章

  1. codeforces#1139F. Dish Shopping (离散化数组数组+ 扫描线)

    膜拜大佬:https://blog.csdn.net/xyz32768/article/details/88831233 题目链接: http://codeforces.com/contest/113 ...

  2. Codeforces 605D - Board Game(树状数组套 set)

    Codeforces 题目传送门 & 洛谷题目传送门 事实上是一道非常容易的题 很容易想到如果 \(c_i\geq a_j\) 且 \(d_i\geq b_j\) 就连一条 \(i\to j\ ...

  3. 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 ...

  4. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  5. 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings

    谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...

  6. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  7. 【BZOJ-1452】Count 树状数组 套 树状数组

    1452: [JSOI2009]Count Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1769  Solved: 1059[Submit][Stat ...

  8. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  9. BZOJ1901 - Dynamic Rankings(树状数组套主席树)

    题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t  要求你把第i个数修改为t 题解 动态的区间第k ...

随机推荐

  1. Java链表讲解

    主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都 ...

  2. 如果Android真的收费了,你怎么看?

    前言 今天突然看到一群里有人发了下面这样一张图片,然后群里又炸了!   于是又和同事讨论了android收费的问题,然后隔壁正在玩农药的UI妹子就笑了... 没错! 安卓可能要收费了!安卓可能要收费了 ...

  3. Synchronizing timer

    http://blog.csdn.net/zjq001x/article/details/53107159 集合点: 简单来理解一下,虽然我们的“性能测试”理解为“多用户并发测试”,但真正的并发是不存 ...

  4. swift 学习- 23 -- 扩展

    // 扩展 就是为一个已有的 类, 结构体, 枚举, 或者 协议类型添加新功能, 这包括在没有权限获取 原始代码的情况下 扩展类型的能力 (即 逆向建模), 扩展和 OC 中的分类类似, (与 OC ...

  5. C# 将Excel转换为PDF

    C# 将Excel转换为PDF 转换场景 将Excel转换为PDF是一个很常用的功能,常见的转换场景有以下三种: 转换整个Excel文档到PDF转换Excel文档的某一个工作表到PDF转换Excel文 ...

  6. 阿里云-AliRepo

    <mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name&g ...

  7. Java调用oracle存储过程通过游标返回临时表数据

    注:本文来源于 <  Java调用oracle存储过程通过游标返回临时表数据   > Java调用oracle存储过程通过游标返回临时表数据 项目开发过程中,不可避免的会用到存储过程返回结 ...

  8. easyui combogrid下拉表格的分页/按键/动态搜索

    作者:xfl4629712  <  easyui combogrid下拉表格的分页/按键/动态搜索  > 需求: 1.下拉框下拉时出现表格: 2.表格带分页功能: 3.可以使用向上键.向下 ...

  9. Java 开源博客 Solo 2.5.0 发布

    Java 开源博客 Solo 2.5.0 发布 Solo 是一款一个命令就能搭建好的 Java 开源博客系统,如果你想开个独立博客,请一定不要错过! 2.5.0 版本主要支持了 Markdown/JS ...

  10. LeetCode(123):买卖股票的最佳时机 III

    Hard! 题目描述: 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意: 你不能同时参与多笔交易(你必 ...