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. ES--05

    第四十一讲!分词器内部组成 内置分词器 课程大纲 1.什么是分词器 切分词语,normalization(提升recall召回率) 给你一段句子,然后将这段句子拆分成一个一个的单个的单词,同时对每个单 ...

  2. 32)django-modelform

    一:mdoelform modelform是model和form结合 model+form =>验证+数据库 class A(model): user= pass= Form: class Lo ...

  3. js的页面传值cookie.session

    jquery的cookie: 读取所有的cookie: document.cookie: 读取单个cookie:$.cookie('cookiename'); 新增cookie: $.cookie(' ...

  4. WebSocket异步通讯,实时返回数据相关问题论坛

    https://stackoverflow.com/questions/23773407/a-websockets-receiveasync-method-does-not-await-the-ent ...

  5. Confluence 6 配置草稿保存的时间

    这个设置仅仅应用到 Confluence 6.0 及后续版本中,如果你选择 禁用(disable )collaborative editing. 当协同编辑被启用后,我们将会保存所有的修改. 当协同编 ...

  6. Java的小实验——各种测试以及说明

    日期:2018.10.07 星期五 博客期:014 一.Java中的位运算 代码如下: package Morts107; public class Test107 { public static v ...

  7. 《剑指offer》顺时针打印矩阵

    本题来自<剑指offer> 顺时针打印矩阵 题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 1 ...

  8. Java 并发类

    java.util.concurrent包里 提供了一批线程安全的类 一. java.util.concurrent.atomic java.util.concurrent.atomic包里的原子处理 ...

  9. 20165314 2016-2017-2 《Java程序设计》第3周学习总结

    20165314 2016-2017-2 <Java程序设计>第3周学习总结 教材学习内容总结 类体包含成员变量和域变量 局部变量只在方法内有效 对象的创建以及对象对自己变量和方法通过用. ...

  10. jQuery常见的几个文档处理方式

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...