bzoj 2527 Meteors - 整体二分 - 树状数组
Description
这个星球经常会下陨石雨。BIU已经预测了接下来K场陨石雨的情况。
BIU的第i个成员国希望能够收集Pi单位的陨石样本。你的任务是判断对于每个国家,它需要在第几次陨石雨之后,才能收集足够的陨石。
输入:
第一行是两个数N,M。
第二行有M个数,第i个数Oi表示第i段轨道上有第Oi个国家的太空站。
第三行有N个数,第i个数Pi表示第i个国家希望收集的陨石数量。
第四行有一个数K,表示BIU预测了接下来的K场陨石雨。
接下来K行,每行有三个数Li,Ri,Ai,表示第K场陨石雨的发生地点在从Li顺时针到Ri的区间中(如果Li<=Ri,就是Li,Li+1,...,Ri,否则就是Ri,Ri+1,...,m-1,m,1,...,Li),向区间中的每个太空站提供Ai单位的陨石样本。
输出:
N行。第i行的数Wi表示第i个国家在第Wi波陨石雨之后能够收集到足够的陨石样本。如果到第K波结束后仍然收集不到,输出NIE。
数据范围:
Input
Output
Sample Input
1 3 2 1 3
10 5 7
3
4 2 4
1 3 1
3 5 2
Sample Output
NIE
1
HINT
Source
因为之前用可持久化线段树被卡内存了,表示不爽,于是用整体二分来"水掉"这道题。
整体二分其实并没有什么特别高端的东西。
单次询问二分答案使得总时间复杂度太高了,所以就把所有操作和询问放到一起进行二分答案。用一个数组来维护答案在当前二分的区间[l, r]内的询问。在每一层中"暴力"进行用数据结构进行计算1 ~ mid的操作对答案的贡献,如果比需求的多或者等于,就扔进左区间的队列,然后递归处理,否则扔进右区间的队列递归处理。
同时注意保障每一层的时间复杂度,最坏的情况下,"解答树"是一棵满二叉树,如果真的是暴力执行 1 ~ mid 的操作和直接二分答案就没什么区别了(所以说要巧妙地利用已有的计算结果)。
对于这道题,这个数据结构就用树状数组就好了(没有必要出动线段树这种大牛数据结构)
Code
/**
* bzoj
* Problem#2527
* Accepted
* Time:13520ms
* Memory:16336k
*/
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;
const signed int inf = (signed)((1u << ) - );
const signed long long llf = (signed long long)((1ull << ) - );
const double eps = 1e-;
const int binary_limit = ;
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
#define max3(a, b, c) max(a, max(b, c))
#define min3(a, b, c) min(a, min(b, c))
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u * ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} #define LL long long
#define lowbit(x) (x & (-x)) typedef class IndexedTree {
public:
LL* a;
int local;
int s;
IndexedTree():a(NULL), s(), local() { }
IndexedTree(int n):s(n), local() {
a = new LL[(n + )];
memset(a, , sizeof(LL) * (n + ));
} inline void add(int idx, LL val) {
for(; idx <= s; idx += lowbit(idx))
a[idx] += val;
} inline void add(int l, int r, LL val) {
add(l, val);
add(r + , -val);
} inline LL getSum(int idx) {
LL rt = ;
for(; idx; idx -= lowbit(idx))
rt += a[idx];
return rt;
}
}IndexedTree; typedef class Updater {
public:
int l;
int r;
int val;
}Updater; int n, m, q;
vector<int> *owns;
int* goals;
Updater *us; inline void init() {
readInteger(n);
readInteger(m);
owns = new vector<int>[(n + )];
goals = new int[(n + )];
for(int i = , x; i <= m; i++) {
readInteger(x);
owns[x].push_back(i);
}
for(int i = ; i <= n; i++)
readInteger(goals[i]);
readInteger(q);
us = new Updater[(q + )];
for(int i = ; i <= q; i++) {
readInteger(us[i].l);
readInteger(us[i].r);
readInteger(us[i].val);
}
us[q + ] = (Updater) {, , };
} inline void modify(IndexedTree& it, int i, int sign) {
if(us[i].l > us[i].r)
it.add(us[i].l, m, us[i].val * sign), it.add(, us[i].r, us[i].val * sign);
else
it.add(us[i].l, us[i].r, us[i].val * sign);
} int* res;
IndexedTree it;
void CDQDividing(queue<int> &que, int l, int r) {
if(que.empty()) return;
if(l == r) {
while(!que.empty()) {
int x = que.front();
que.pop();
res[x] = l;
}
return;
} int mid = (l + r) >> ;
while(it.local < mid)
modify(it, ++it.local, );//, cntit++;
while(it.local > mid)
modify(it, it.local--, -);//, cntit++; // fprintf(stderr, "dep-%d time %dms %d", dep, clock(), cntit); queue<int> ql, qr;
while(!que.empty()) {
int i = que.front();
que.pop();
LL s = ;
for(int j = ; j < (signed)owns[i].size() && s <= goals[i]; j++)
s += it.getSum(owns[i][j]);
if(s < goals[i])
qr.push(i);
else
ql.push(i);
} // while(!que.empty()) que.pop();
// memset(it.a, 0, sizeof(LL) * (m + 2));
CDQDividing(ql, l, mid);
CDQDividing(qr, mid + , r);
} queue<int> que;
inline void solve() {
res = new int[(n + )];
for(int i = ; i <= n; i++)
que.push(i);
it = IndexedTree(m + );
CDQDividing(que, , q + );
for(int i = ; i <= n; i++)
if(res[i] <= q)
printf("%d\n", res[i]);
else
puts("NIE");
} int main() {
// freopen("meteors.in", "r", stdin);
// freopen("meteors.out", "w", stdout);
init();
solve();
return ;
}
bzoj 2527 Meteors - 整体二分 - 树状数组的更多相关文章
- 【BZOJ-2527】Meteors 整体二分 + 树状数组
2527: [Poi2011]Meteors Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 831 Solved: 306[Submit][Stat ...
- 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组
题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...
- BZOJ2527[Poi2011]Meteors——整体二分+树状数组
题目描述 Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby galaxy. The ...
- BZOJ2527 [Poi2011]Meteors 整体二分 树状数组
原文链接http://www.cnblogs.com/zhouzhendong/p/8686460.html 题目传送门 - BZOJ2527 题意 有$n$个国家. 太空里有$m$个太空站排成一个圆 ...
- BZOJ 2527 [Poi2011]Meteors (整体二分+树状数组)
整体二分板题,没啥好讲的-注意是个环-还有所有贡献会爆longlong,那么只要在加之前判断一下有没有达到需要的值就行了- CODE #include <set> #include < ...
- 【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个位置,每个位 ...
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...
随机推荐
- 【cocos2d-js官方文档】事件分发监听机制(摘录)
简介 游戏开发中一个很重要的功能就是交互,如果没有与用户的交互,那么游戏将变成动画,而处理用户交互就需要使用事件监听器了. 总概: 事件监听器(cc.EventListener) 封装用户的事件处理逻 ...
- Could not find result map java.lang.Integer] with root cause
错误的代码 <select id="selectpGoodsInfoIdByGoodsId" parameterType="java.lang.Integer&qu ...
- sqli-labs(十八)
第五十五关:和上一关类似,只是拼凑的方法不一样,所以需要先判断后台是怎么拼凑的 分别输入id=1'--+ id=1"--+ id=') --+ ...
- sqli-labs(六)
第十一关: 这关是一个登陆口,也是一个sql注入的漏洞,也就是常说的万能密码. 在输入框账号密码种分别输入 1' 和1' 页面会报错. 后台使用的单引符号进行的拼接.账号输入1' or '1'=' ...
- MySQL.配置MariaDB的字符集
配置MariaDB的字符集 环境: 操作系统:CentOS Linux release 7.x mariadb安装及配置 yum install mariadb-server mariadb #安装 ...
- LeetCode69.x的平方根
实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 输出: 2 示例 ...
- beego 初体验 - 环境搭建
首先,安装go运行时和beego beego,在git bash 运行命令: go get github.com/beego/bee go get github.com/astaxie/beego g ...
- kali linux dns劫持
1,確定局域網ip 2,修改/etc/ettercap/etter.dns 添加自己的ip和劫持域名 3,/var/www/index.html (修改html页面替换被劫持的 ...
- python 文件写入错误
在保存网页文字到txt文件下时,出现如下错误 UnicodeEncodeError: 'gbk' codec can't encode character u'\xa9' in position 24 ...
- NFS配置与安装
安装 1 环境描述: * 网络环境: NFS server: 192.168.102.47 NFS client: 192.1 ...