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 }