parallel binary search SPOJMeteors
来源:互联网 发布:淘宝网衣架 编辑:程序博客网 时间:2024/06/14 06:12
题目链接
题目大意:有m个空间站组成一个环形的轨道,每个空间站属于n个国家之一。一次流星雨可以给一段连续的空间站带来同样数量的陨石样本。给出每个国家需要的陨石数量和流星雨的出现情况,问每个国家最快在多少次流星雨前就能收集到需要数量的陨石。
解题思路:离线、并行二分搜索。首先可以二分判断每个国家的答案。“并行”在这里是一个形象的比喻,即判断(MID)答案是否正确时可以在O(n)的时间内判断出每个国家的答案。
该题中间计算结果会超过64位整数,wa了许久。。
#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <iomanip>#include <iostream>#include <cassert>#include <map>#include <set>#include <queue>#include <stack>#include <vector>#define RD(x) scanf("%d", &x)#define REP(i, n) for (int i=0; i<int(n); i++)#define FOR(i, n) for (int i=1; i<=int(n); i++)#define pii pair<int, int>#define mp make_pair#define pb push_backinline int read(){int ret; scanf("%d", &ret); return ret;}using namespace std;#define N 345678#define M 22222#define eps 1e-8#define pi acos(-1.0)#define inf 0X5FFFFFFFFFFFFFFFll#define mod 1000000007ll#define LL long long#define ULL unsigned long longLL add[N];int n, m, K;void buildtree() {memset(add, 0, sizeof add);}void update(int x, LL val) {while (x <= m) {add[x] += val;x += x & (-x);}}void update(int l, int r, LL val) {update(l, val);update(r+1, -val);}LL get(int x) {LL ret = 0;while (x > 0) {ret += add[x];x -= x & (-x);}return ret;}LL p[N];int l[N], r[N];LL w[N];void update(int id) {if (l[id] <= r[id])update(l[id], r[id], w[id]);elseupdate(1, r[id], w[id]), update(l[id], m, w[id]);}vector<int> has[N];int lans[N], rans[N], mans[N];bool suc[N];void parallelbinarysearch() {static pii a[N];int all = 0;FOR(i, n) if (lans[i] != rans[i]) {a[all].first = mans[i];a[all].second = i;all++;}sort(a, a + all);buildtree();int t = 1;REP(i, all) {int id = a[i].second;while (t <= K && t <= a[i].first)update(t++);LL tmp = 0;suc[id] = false;REP(j, has[id].size()) {tmp += get(has[id][j]);if (tmp >= p[id])suc[id] = true;}}}int Main() {RD(n);RD(m);FOR(i, m) {int x;RD(x);has[x].push_back(i);}FOR(i, n)p[i] = read();RD(K);FOR(i, K) {RD(l[i]);RD(r[i]);w[i] = read();}FOR(i, n)lans[i] = 1, rans[i] = K+1;while (true) {FOR(i, n)mans[i] = (lans[i] + rans[i]) >> 1;parallelbinarysearch();FOR(i, n) if (lans[i] != rans[i]) {if (suc[i])rans[i] = mans[i];elselans[i] = mans[i] + 1;}bool ok = true;FOR(i, n)if (lans[i] != rans[i])ok = false;if (ok)break;}FOR(i, n)if (lans[i] <= K)printf("%d\n", lans[i]);elseputs("NIE");return 0;}int main() {return Main();}
0 0
- parallel binary search SPOJMeteors
- Binary search
- Binary Search
- Binary Search
- binary search
- binary search
- Binary Search
- binary search
- binary search
- binary search
- binary search
- binary search
- binary search
- Binary Search
- Binary search
- Binary Search
- Binary Search
- Binary Search
- GoogleForChina是不是解决了Google搜索的问题?
- HDU's ACM 1133 Buy The Tickets
- GNU Build System
- 深入理解linux网络内幕---专业词汇
- android 常用方法集合
- parallel binary search SPOJMeteors
- [Erlang危机](5.0)运行时指标
- 第11周项目6反序数
- 子查询
- 怎么备份织梦网站数据 网站备份教程
- java类的结构的内存解析
- Uboot启动流程分析
- C语言指针举例(From(新浪微博:@M了个J))学习笔记
- IP地址、子网掩码、默认网关、DNS服务器、DHCP服务器详解