NOIP模拟 Work - 二分 + 树状数组 / ???

题目分析
如果没有最后的注意事项,此题就是二分裸题。有了注意事项,会有两种思路:
- 在线:二分天数t,并在主席树上求1~t天中大于d(浪费的时间)的时间之和以及数量,答案即为:sum - d * cnt 无奈写的丑,卡卡只能过6、7个点。
- 离线:简单考虑,既然要求大于等于d的和以及数量,不妨按照d来排序,再把t也排序。每次将大于等于d的t加入树状数组(记录和以及数量),这样就能直接查出和和数量。 AC。
code
树状数组 AC
#include<bits/stdc++.h>
using namespace std;
const int N = 200005, M = 1000005;
typedef long long ll;
int n, m, anss[N];
int pointer;
typedef pair<int, int> P;
typedef pair<ll, int> ansP;
P t[N];
struct BIT{
ll sum[N], cnt[N];
inline void add(int x, ll v, int c){
for(int i = x; i <= m; i += (i&-i))
sum[i] += v, cnt[i] += c;
}
inline ansP query(int x){
ansP ret = P(0, 0);
for(int i = x; i; i -= (i&-i))
ret.first += sum[i], ret.second += cnt[i];
return ret;
}
}bit;
struct node{
int d, r, id;
inline bool operator < (const node &b) const{
return d < b.d;
}
}s[N];
inline int read(){
int i = 0, f = 1; char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch -'0');
return i * f;
}
inline void wr(int x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) wr(x / 10);
putchar(x % 10 + '0');
}
inline bool calc(int mid, int d, int r){
ansP tmp = bit.query(mid);
ll ret = tmp.first - 1LL * d * tmp.second;
return ret >= r;
}
int main(){
n = read(), m = read();
for(int i = 1; i <= m; i++) t[i].first = read(), t[i].second = i;
for(int i = 1; i <= n; i++) s[i].d = read(), s[i].r = read(), s[i].id = i;
sort(t + 1, t + m + 1), sort(s + 1, s + n + 1);
pointer = m;
for(int i = n; i >= 1; i--){
while(t[pointer].first >= s[i].d && pointer >= 1) bit.add(t[pointer].second, t[pointer].first, 1), pointer--;
int l = 1, r = m, ans = 0;
while(l <= r){
int mid = l + r >> 1;
if(calc(mid, s[i].d, s[i].r)) ans = mid, r = mid - 1;
else l = mid + 1;
}
anss[s[i].id] = ans;
}
for(int i = 1; i <= n; i++) wr(anss[i]), putchar(' ');
return 0;
}
主席树 50 ~ 60
#include<bits/stdc++.h>
using namespace std;
const int N = 200005, M = 1000005;
typedef long long ll;
struct node{
node *lc, *rc;
ll sum, cnt;
inline void upt(){
sum = lc->sum + rc->sum;
cnt = lc->cnt + rc->cnt;
}
}pool[N * 20], *tail = pool, *null = pool, *rt[N];
int maxx = -1;
typedef pair<ll, ll> ansP;
int n, m, d[N], rr[N];
int t[N], b[N * 2], len;
ll tsum[N];
inline int read(){
int i = 0, f = 1; char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch -'0');
return i * f;
}
inline void wr(int x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) wr(x / 10);
putchar(x % 10 + '0');
}
inline void insert(node *x, node *&y, int l, int r, int v){
y = ++tail;
y->lc = x->lc, y->rc = x->rc;
y->sum = x->sum, y->cnt = x->cnt;
y->sum += b[v];
y->cnt++;
if(l == r) return;
int mid = l + r >> 1;
if(v <= mid) insert(x->lc, y->lc, l, mid, v);
else insert(x->rc, y->rc, mid + 1, r, v);
y->upt();
}
inline ansP query(node *nl, node *nr, int l, int r, int x, int y){
if(x <= l && r <= y) return ansP(nr->sum - nl->sum, nr->cnt - nl->cnt);
int mid = l + r >> 1;
ansP ret = ansP(0, 0);
if(x <= mid){
ansP tmp = query(nl->lc, nr->lc, l, mid, x, y);
ret.first += tmp.first;
ret.second += tmp.second;
}
if(y > mid){
ansP tmp = query(nl->rc, nr->rc, mid + 1, r, x, y);
ret.first += tmp.first;
ret.second += tmp.second;
}
return ret;
}
bool flag;
inline bool calc(int mid, int d, int r){
ansP tmp = query(rt[0], rt[mid], 1, maxx, d, maxx);
ll ret = tmp.first - 1LL * b[d] * tmp.second;
return ret >= r;
}
inline void disc_init(){
sort(b + 1, b + len + 1);
len = unique(b + 1, b + len + 1) - (b + 1);
for(int i = 1; i <= m; i++) t[i] = lower_bound(b + 1, b + len + 1, t[i]) - b;
for(int i = 1; i <= n; i++) d[i] = lower_bound(b + 1, b + len + 1, d[i]) - b;
}
int main(){
freopen("h.in", "r", stdin);
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
n = read(), m = read();
null->lc = null->rc = null, null->sum = null->cnt = 0;
for(int i = 1; i <= m; i++) t[i] = b[++len] = read(), maxx = max(maxx, t[i]);
for(int i = 1; i <= n; i++) d[i] = b[++len] = read(), rr[i] = read();
disc_init();
rt[0] = null;
for(int i = 1; i <= m; i++)
insert(rt[i - 1], rt[i], 1, maxx, t[i]);
for(int i = 1; i <= n; i++){
int l = 1, r = m, ans = 0;
if(d[i] > maxx){
putchar('0'),putchar(' ');
continue;
}
while(l <= r){
int mid = l + r >> 1;
if(calc(mid, d[i], rr[i])) ans = mid, r = mid - 1;
else l = mid + 1;
}
cout << ans << " ";
}
}
NOIP模拟 Work - 二分 + 树状数组 / ???的更多相关文章
- 2018.10.08 NOIP模拟 栅栏(树状数组+rand)
传送门 今天的送分题. 首先考虑每次给要围上栅栏的矩阵里的整体加上1,如果栅栏被撤销就整体减1,最后比较两个点的值是否相同来进行判断. 然而这样的效果并不理想,很容易卡掉. 进一步思考,我们第iii次 ...
- 【BZOJ-2527】Meteors 整体二分 + 树状数组
2527: [Poi2011]Meteors Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 831 Solved: 306[Submit][Stat ...
- 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组
BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...
- bzoj千题计划316:bzoj3173: [Tjoi2013]最长上升子序列(二分+树状数组)
https://www.lydsy.com/JudgeOnline/problem.php?id=3173 插入的数是以递增的顺序插入的 这说明如果倒过来考虑,那么从最后一个插入的开始删除,不会对以某 ...
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- zoj-3963 Heap Partition(贪心+二分+树状数组)
题目链接: Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence ...
- 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...
- 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组
题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...
随机推荐
- js常用数据转换&判断
数组转字符串 var a, b; a = new Array(0,1,2,3,4); b = a.join("-"); //"0-1-2-3-4" 字符串转数组 ...
- Appium_Python_API
1) find_element_by_android_uiautomator (‘new UiSelector().text(“XXXX”)’).click 正常匹配2) find_element_b ...
- 【Codeforces Round #446 (Div. 2) C】Pride
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 想一下,感觉最后的结果肯定是从某一段开始,这一段的gcd为1,然后向左和向右扩散的. 则枚举那一段在哪个地方. 我们设这一段中所有的 ...
- oracle里long类型的总结
转自原文oracle中long类型为什么不推荐使用 不是不推荐使用的,是一般用不到,而有些时候是会用到的,所以不能一概而论.1.LONG 数据类型中存储的是可变长字符串,最大长度限制是2GB.2.对于 ...
- 四种布局JS
现代 Web 开发在将体验和功能做到极致的同时,对于美观的追求也越来越高.在推荐完图形库之后,再来推荐一些精品的独立 UI 组件.这些组件可组合在一起,形成美观而交互强大的 Web UI . 给 We ...
- tensorflow compile
bazel build --spawn_strategy=standalone tensorflow/examples/label_image/...
- 【习题 3-12 UVA - 11809】Floating-Point Numbers
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] \(A*10^B = temp[M]*2^{2^E-1}\) 两边取一下对数 得到 \(lg_A+B = lg_{temp[M]} ...
- 【Codeforces Round #433 (Div. 2) B】Maxim Buys an Apartment
[链接]h在这里写链接 [题意] 你有n个位置,然后其中有k个地方是已经被人占据了的. 一个"好的位置"的定义是指,这个位置相邻的地方其中至少有一个被人占据了. k个被人占据的位置 ...
- Linux下开启关闭防火墙
一.Linux下开启/关闭防火墙命令 1) 永久性生效,重启后不会复原 开启: chkconfig iptables on 关闭: chkconfig iptables off 2) 即时生效,重 ...
- OC学习篇之---Foundation框架中的其他类(NSNumber,NSDate,NSExcetion)
1.NSNumber 这个类主要是用来封装基本类型的,说到这里,就不得不说一下了: OC中的集合是不允许存入基本类型的,所以NSNumber类就诞生了,需要将基本类型封装一下,然后存进去,这个类似于J ...