题目分析

如果没有最后的注意事项,此题就是二分裸题。有了注意事项,会有两种思路:

  • 在线:二分天数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 - 二分 + 树状数组 / ???的更多相关文章

  1. 2018.10.08 NOIP模拟 栅栏(树状数组+rand)

    传送门 今天的送分题. 首先考虑每次给要围上栅栏的矩阵里的整体加上1,如果栅栏被撤销就整体减1,最后比较两个点的值是否相同来进行判断. 然而这样的效果并不理想,很容易卡掉. 进一步思考,我们第iii次 ...

  2. 【BZOJ-2527】Meteors 整体二分 + 树状数组

    2527: [Poi2011]Meteors Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 831  Solved: 306[Submit][Stat ...

  3. 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  4. BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...

  5. bzoj千题计划316:bzoj3173: [Tjoi2013]最长上升子序列(二分+树状数组)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3173 插入的数是以递增的顺序插入的 这说明如果倒过来考虑,那么从最后一个插入的开始删除,不会对以某 ...

  6. 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  7. zoj-3963 Heap Partition(贪心+二分+树状数组)

    题目链接: Heap Partition Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A sequence ...

  8. 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组

    题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...

  9. 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组

    题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...

随机推荐

  1. android开发设计辅助工具整理

    1.Button设计工具button设计

  2. Altium Designer如何统一改变pcb状态下的原件标号位置

    原创 我用的是Altium Designer16版本 变成 步骤如下: 选中标号 右击 下边一步很重要: 点击应用和确定 在之后弹出的对话框中选则你要改变的位置,我这里是把标号改变到原件的右侧: 等待 ...

  3. SQL Server 中计算农历

    1.建一表,放初始化资料   因为农历的日期,是由天文学家推算出来的,到现在只有到2049年的,以后的有了还可以加入!   CREATE TABLE SolarData ( yearId int no ...

  4. Oracle 排序问题(null带来的)

    null 导致排序有问题, 对于数字的,一定要用nvl来解决.

  5. Android ListView带CheckBox实现单选

    第1种方法: 首先是我们的bean: public class Bean { private boolean isChecked; private String msg = "这是一条测试数 ...

  6. 使用wepy开发微信小程序商城第一篇:项目初始化

    使用wepy开发微信小程序商城 第一篇:项目初始化 前言: wepy小程序项目初始化的操作,官方文档看了好几遍,感觉写得不是很清楚. 这篇写得挺好的:小程序开发之wepy 1.初始化项目 (1)全局安 ...

  7. POJ 1753 Flip Game DFS枚举

    看题传送门:http://poj.org/problem?id=1753 DFS枚举的应用. 基本上是参考大神的.... 学习学习.. #include<cstdio> #include& ...

  8. [Angular HTML] Overwrite input value, String.fromCharCode & input.selectionStart

    @HostListener('keydown', ['$event', '$event.keyCode']) onKeyDown($event: KeyboardEvent, keyCode) { i ...

  9. tensorflow 的 Batch Normalization 实现(tf.nn.moments、tf.nn.batch_normalization)

    tensorflow 在实现 Batch Normalization(各个网络层输出的归一化)时,主要用到以下两个 api: tf.nn.moments(x, axes, name=None, kee ...

  10. matlab 程序发布

    将matlab程序发布为可执行程序包 说明,这种可执行程序包可以在没有安装matlab的计算机上运行. 1. 打开Applicaiton Compler 如果下拉列表中没有这个APPLICATIOND ...