SPOJ Meteors - 可持久化线段树 - 二分法

Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby galaxy. The planet is unsuitable for colonisation due to strange meteor showers, which on the other hand make it an exceptionally interesting object of study.

The member states of BIU have already placed space stations close to the planet's orbit. The stations' goal is to take samples of the rocks flying by. The BIU Commission has partitioned the orbit into SPOJ Meteors - 可持久化线段树 - 二分法 sectors, numbered from SPOJ Meteors - 可持久化线段树 - 二分法 to SPOJ Meteors - 可持久化线段树 - 二分法, where the sectors SPOJ Meteors - 可持久化线段树 - 二分法 and SPOJ Meteors - 可持久化线段树 - 二分法 are adjacent. In each sector there is a single space station, belonging to one of the SPOJ Meteors - 可持久化线段树 - 二分法 member states.

Each state has declared a number of meteor samples it intends to gather before the mission ends. Your task is to determine, for each state, when it can stop taking samples, based on the meter shower predictions for the years to come.

Input

The first line of the standard input gives two integers, SPOJ Meteors - 可持久化线段树 - 二分法 and SPOJ Meteors - 可持久化线段树 - 二分法 (SPOJ Meteors - 可持久化线段树 - 二分法), separated by a single space, that denote, respectively, the number of BIU member states and the number of sectors the orbit has been partitioned into.

In the second line there are SPOJ Meteors - 可持久化线段树 - 二分法 integers SPOJ Meteors - 可持久化线段树 - 二分法 (SPOJ Meteors - 可持久化线段树 - 二分法), separated by single spaces, that denote the states owning stations in successive sectors.

In the third line there are SPOJ Meteors - 可持久化线段树 - 二分法 integers SPOJ Meteors - 可持久化线段树 - 二分法 (SPOJ Meteors - 可持久化线段树 - 二分法), separated by single spaces, that denote the numbers of meteor samples that the successive states intend to gather.

In the fourth line there is a single integer SPOJ Meteors - 可持久化线段树 - 二分法 (SPOJ Meteors - 可持久化线段树 - 二分法) that denotes the number of meteor showers predictions. The following SPOJ Meteors - 可持久化线段树 - 二分法 lines specify the (predicted) meteor showers chronologically. The SPOJ Meteors - 可持久化线段树 - 二分法-th of these lines holds three integers SPOJ Meteors - 可持久化线段树 - 二分法SPOJ Meteors - 可持久化线段树 - 二分法SPOJ Meteors - 可持久化线段树 - 二分法(separated by single spaces), which denote that a meteor shower is expected in sectors SPOJ Meteors - 可持久化线段树 - 二分法 (if SPOJ Meteors - 可持久化线段树 - 二分法) or sectors SPOJ Meteors - 可持久化线段树 - 二分法 (if SPOJ Meteors - 可持久化线段树 - 二分法), which should provide each station in those sectors with SPOJ Meteors - 可持久化线段树 - 二分法 meteor samples (SPOJ Meteors - 可持久化线段树 - 二分法).

Output

Your program should print SPOJ Meteors - 可持久化线段树 - 二分法 lines on the standard output. The SPOJ Meteors - 可持久化线段树 - 二分法-th of them should contain a single integer SPOJ Meteors - 可持久化线段树 - 二分法, denoting the number of shower after which the stations belonging to the SPOJ Meteors - 可持久化线段树 - 二分法-th state are expected to gather at least SPOJ Meteors - 可持久化线段树 - 二分法 samples, or the wordNIE (Polish for no) if that state is not expected to gather enough samples in the foreseeable future.

Example

For the input data:

3 5
1 3 2 1 3
10 5 7
3
4 2 4
1 3 1
3 5 2

the correct result is:

3
NIE
1

  题目大意 一个星球的环形轨道上有m个空间站,每个空间站属于n个国家中的一个,有k次流星雨,每次会使得一段空间站可以获得一些陨石,每个国家有个收集目标,问每个国家在第多少次流星雨后达成目标,或者无法达到目标。

  将每次流星雨当成一次区间修改,修改可持久化线段树。用vector存下每个国家有哪些空间站。

  然后枚举每个国家,二分答案,判断的时候暴力枚举每个国家的空间站,进行查询。

  好在spoj不卡空间,bzoj空间直接卡死。然后我发现似乎我算节点数的时候忘记算常数了,发现内存池开小了很多,所以就动态开节点慢了许多。

Code

 /**
* SPOJ
* Problem#METEORS
* Accepted
* Time:3220ms
* Memory:521216k
*/
#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>
#include <stack>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;
const signed int inf = (signed)((1u << ) - );
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 << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} #define LL long long typedef class SegTreeNode {
public:
LL val;
LL lazy;
SegTreeNode *l, *r; SegTreeNode():val(), lazy(), l(NULL), r(NULL) { } inline void pushUp() {
val = l->val + r->val;
}
}SegTreeNode; #define LIMIT 5600000
SegTreeNode pool[LIMIT + ];
int top = ; inline SegTreeNode* newnode() {
if(top >= LIMIT) return new SegTreeNode();
return &pool[top++];
} inline SegTreeNode* newnode(SegTreeNode*& b) {
if(top >= LIMIT) {
SegTreeNode* p = new SegTreeNode();
*p = *b;
return p;
}
pool[top] = *b;
return &pool[top++];
} typedef class DurableSegTree {
public:
int now, n;
SegTreeNode** ls; DurableSegTree() { }
DurableSegTree(int n, int limit):now(), n(n) {
ls = new SegTreeNode*[(limit + )];
build(ls[], , n);
} void build(SegTreeNode*& node, int l, int r) {
node = newnode();
if(l == r) return;
int mid = (l + r) >> ;
build(node->l, l, mid);
build(node->r, mid + , r);
} void update(SegTreeNode*& old, SegTreeNode*& newo, int l, int r, int ql, int qr, LL val) {
newo = newnode(old);
if(ql > qr) return;
if(ql == l && qr == r) {
newo->lazy += val;
newo->l = old->l, newo->r = old->r;
return;
}
int mid = (l + r) >> ;
if(qr <= mid) {
newo->r = old->r;
update(old->l, newo->l, l, mid, ql, qr, val);
} else if(ql > mid){
newo->l = old->l;
update(old->r, newo->r, mid + , r, ql, qr, val);
} else {
update(old->l, newo->l, l, mid, ql, mid, val);
update(old->r, newo->r, mid + , r, mid + , qr, val);
}
newo->val += val * 1LL * (qr - ql + );
} inline void update(int l, int r, LL val) {
if(l <= r) {
update(ls[now], ls[now + ], , n, l, r, val);
} else {
update(ls[now], ls[now + ], , n, r + , l - , -val);
ls[now + ]->lazy += val;
}
now++;
} void query(SegTreeNode*& node, int l, int r, int idx, LL& ret) {
ret += node->lazy;
if(l == idx && r == idx) {
ret += node->val;
return;
}
int mid = (l + r) >> ;
if(idx <= mid) query(node->l, l, mid, idx, ret);
else query(node->r, mid + , r, idx, ret);
} inline LL query(int k, int pos) {
LL ret = ;
query(ls[k], , n, pos, ret);
return ret;
}
}DurableSegTree; int n, m, q;
vector<int> *owns;
int *goals;
DurableSegTree dst; 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);
dst = DurableSegTree(m, q + );
for(int i = , a, b, c; i <= q; i++) {
readInteger(a);
readInteger(b);
readInteger(c);
dst.update(a, b, c);
}
} boolean check(int country, int mid) {
LL ret = ;
for(int i = ; i < (signed)owns[country].size() && ret < goals[country]; i++)
ret += dst.query(mid, owns[country][i]);
return ret >= goals[country];
} inline void solve() {
for(int c = ; c <= n; c++) {
int l = , r = q;
while(l <= r) {
int mid = (l + r) >> ;
if(check(c, mid)) r = mid - ;
else l = mid + ;
}
if(r == q) puts("NIE");
else printf("%d\n", r + );
}
} int main() {
// freopen("meteors.in", "r", stdin);
init();
solve();
return ;
}
上一篇:数据库左右连接on后的限制条件问题


下一篇:邮件发送 utils