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  sectors, numbered from  to , where the sectors  and  are adjacent. In each sector there is a single space station, belonging to one of the  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,  and  (), 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  integers  (), separated by single spaces, that denote the states owning stations in successive sectors.

In the third line there are  integers  (), 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  () that denotes the number of meteor showers predictions. The following  lines specify the (predicted) meteor showers chronologically. The -th of these lines holds three integers (separated by single spaces), which denote that a meteor shower is expected in sectors  (if ) or sectors  (if ), which should provide each station in those sectors with  meteor samples ().

Output

Your program should print  lines on the standard output. The -th of them should contain a single integer , denoting the number of shower after which the stations belonging to the -th state are expected to gather at least  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

  1 /**
  2  * SPOJ
  3  * Problem#METEORS
  4  * Accepted
  5  * Time:3220ms
  6  * Memory:521216k
  7  */
  8 #include <iostream>
  9 #include <cstdio>
 10 #include <ctime>
 11 #include <cmath>
 12 #include <cctype>
 13 #include <cstring>
 14 #include <cstdlib>
 15 #include <fstream>
 16 #include <sstream>
 17 #include <algorithm>
 18 #include <map>
 19 #include <set>
 20 #include <stack>
 21 #include <queue>
 22 #include <vector>
 23 #include <stack>
 24 #ifndef WIN32
 25 #define Auto "%lld"
 26 #else
 27 #define Auto "%I64d"
 28 #endif
 29 using namespace std;
 30 typedef bool boolean;
 31 const signed int inf = (signed)((1u << 31) - 1);
 32 const double eps = 1e-6;
 33 const int binary_limit = 128;
 34 #define smin(a, b) a = min(a, b)
 35 #define smax(a, b) a = max(a, b)
 36 #define max3(a, b, c) max(a, max(b, c))
 37 #define min3(a, b, c) min(a, min(b, c))
 38 template<typename T>
 39 inline boolean readInteger(T& u){
 40     char x;
 41     int aFlag = 1;
 42     while(!isdigit((x = getchar())) && x != '-' && x != -1);
 43     if(x == -1) {
 44         ungetc(x, stdin);    
 45         return false;
 46     }
 47     if(x == '-'){
 48         x = getchar();
 49         aFlag = -1;
 50     }
 51     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
 52     ungetc(x, stdin);
 53     u *= aFlag;
 54     return true;
 55 }
 56 
 57 #define LL long long
 58 
 59 typedef class SegTreeNode {
 60     public:
 61         LL val;
 62         LL lazy;
 63         SegTreeNode *l, *r;
 64         
 65         SegTreeNode():val(0), lazy(0), l(NULL), r(NULL) {        }
 66         
 67         inline void pushUp() {
 68             val = l->val + r->val;
 69         }
 70 }SegTreeNode;
 71 
 72 #define LIMIT 5600000
 73 SegTreeNode pool[LIMIT + 1];
 74 int top = 0;
 75 
 76 inline SegTreeNode* newnode() {
 77     if(top >= LIMIT)    return new SegTreeNode();
 78     return &pool[top++];
 79 }
 80 
 81 inline SegTreeNode* newnode(SegTreeNode*& b) {
 82     if(top >= LIMIT) {
 83         SegTreeNode* p = new SegTreeNode();
 84         *p = *b;
 85         return p;
 86     }
 87     pool[top] = *b;
 88     return &pool[top++];
 89 }
 90 
 91 typedef class DurableSegTree {
 92     public:
 93         int now, n;
 94         SegTreeNode** ls;
 95         
 96         DurableSegTree() { }
 97         DurableSegTree(int n, int limit):now(0), n(n) {
 98             ls = new SegTreeNode*[(limit + 1)];
 99             build(ls[0], 1, n);
100         } 
101         
102         void build(SegTreeNode*& node, int l, int r) {
103             node = newnode();
104             if(l == r)    return;
105             int mid = (l + r) >> 1;
106             build(node->l, l, mid);
107             build(node->r, mid + 1, r);
108         }
109         
110         void update(SegTreeNode*& old, SegTreeNode*& newo, int l, int r, int ql, int qr, LL val) {
111             newo = newnode(old);
112             if(ql > qr)    return;
113             if(ql == l && qr == r) {
114                 newo->lazy += val;
115                 newo->l = old->l, newo->r = old->r; 
116                 return;
117             }
118             int mid = (l + r) >> 1;
119             if(qr <= mid) {
120                 newo->r = old->r;
121                 update(old->l, newo->l, l, mid, ql, qr, val);
122             } else if(ql > mid){
123                 newo->l = old->l;
124                 update(old->r, newo->r, mid + 1, r, ql, qr, val);
125             } else {
126                 update(old->l, newo->l, l, mid, ql, mid, val);
127                 update(old->r, newo->r, mid + 1, r, mid + 1, qr, val);
128             }
129             newo->val += val * 1LL * (qr - ql + 1);
130         }
131         
132         inline void update(int l, int r, LL val) {
133             if(l <= r) {
134                 update(ls[now], ls[now + 1], 1, n, l, r, val);
135             } else {
136                 update(ls[now], ls[now + 1], 1, n, r + 1, l - 1, -val);
137                 ls[now + 1]->lazy += val;
138             }
139             now++;
140         } 
141         
142         void query(SegTreeNode*& node, int l, int r, int idx, LL& ret) {
143             ret += node->lazy;
144             if(l == idx && r == idx) {
145                 ret += node->val;
146                 return;
147             }
148             int mid = (l + r) >> 1;
149             if(idx <= mid)    query(node->l, l, mid, idx, ret);
150             else query(node->r, mid + 1, r, idx, ret);
151         }
152         
153         inline LL query(int k, int pos) {
154             LL ret = 0;
155             query(ls[k], 1, n, pos, ret);
156             return ret;
157         }
158 }DurableSegTree;
159 
160 int n, m, q;
161 vector<int> *owns;
162 int *goals;
163 DurableSegTree dst;
164 
165 inline void init() {
166     readInteger(n);
167     readInteger(m);
168     owns = new vector<int>[n + 1];
169     goals = new int[(n + 1)];
170     for(int i = 1, x; i <= m; i++) {
171         readInteger(x);
172         owns[x].push_back(i);
173     }
174     for(int i = 1; i <= n; i++)
175         readInteger(goals[i]);
176 
177     readInteger(q);
178     dst = DurableSegTree(m, q + 1);
179     for(int i = 1, a, b, c; i <= q; i++) {
180         readInteger(a);
181         readInteger(b);
182         readInteger(c);
183         dst.update(a, b, c);
184     }
185 }
186 
187 boolean check(int country, int mid) {
188     LL ret = 0;
189     for(int i = 0; i < (signed)owns[country].size() && ret < goals[country]; i++)
190         ret += dst.query(mid, owns[country][i]);
191     return ret >= goals[country];
192 }
193 
194 inline void solve() {
195     for(int c = 1; c <= n; c++) {
196         int l = 1, r = q;
197         while(l <= r) {
198             int mid = (l + r) >> 1;
199             if(check(c, mid))    r = mid - 1;
200             else l = mid + 1;
201         }
202         if(r == q)    puts("NIE");
203         else printf("%d\n", r + 1);
204     }
205 }
206 
207 int main() {
208 //    freopen("meteors.in", "r", stdin);
209     init();
210     solve();
211     return 0;
212 }
posted @ 2017-07-16 16:33  阿波罗2003  阅读(285)  评论(0编辑  收藏  举报