題意:有n個任務,第i個的存在時間是li~ri,有個權值。求t時刻第k大的權值。數組
這毒瘤...原本是前綴和 -> 主席樹,我是樹套樹...而後光榮TLE。ide
其實很裸。一開始我寫的是每一個位置維護一個權值線段樹。由於要片改點查,就用差分 + 樹狀數組搞定了。而後超時...spa
仔細思考,發現不帶修能夠直接用主席樹。code
把差分數組插入進去就好了,查詢就是前綴和。這麼一看好像主席樹就是同時對多個數組作前綴和,每一個數組就是線段樹的一個位置。blog
我沒用標記永久化,標記下傳的時候直接新建的節點。it
1 #include <cstdio> 2 #include <algorithm> 3 #include <vector> 4 5 typedef long long LL; 6 const int N = 100010, lm = 1e7, M = 20000010; 7 8 int n, m, tot, rt[N]; 9 int sum[M], ls[M], rs[M]; 10 LL Val[M]; 11 std::vector<int> d[N]; 12 13 void insert(int x, int &y, int p, int v, int l, int r) { 14 if(!y || x == y) { 15 y = ++tot; 16 sum[y] = sum[x]; 17 Val[y] = Val[x]; 18 } 19 if(l == r) { 20 sum[y] += v; 21 Val[y] += v * r; 22 return; 23 } 24 if(!ls[y]) { 25 ls[y] = ls[x]; 26 } 27 if(!rs[y]) { 28 rs[y] = rs[x]; 29 } 30 int mid = (l + r) >> 1; 31 if(p <= mid) { 32 insert(ls[x], ls[y], p, v, l, mid); 33 } 34 else { 35 insert(rs[x], rs[y], p, v, mid + 1, r); 36 } 37 sum[y] = sum[ls[y]] + sum[rs[y]]; 38 Val[y] = Val[ls[y]] + Val[rs[y]]; 39 return; 40 } 41 42 LL ask(int k, int l, int r, int o) { 43 if(!o) { 44 return 0; 45 } 46 if(l == r) { 47 return 1ll * std::min(k, sum[o]) * r; 48 } 49 int mid = (l + r) >> 1; 50 if(k <= sum[ls[o]]) { 51 return ask(k, l, mid, ls[o]); 52 } 53 else { 54 return Val[ls[o]] + ask(k - sum[ls[o]], mid + 1, r, rs[o]); 55 } 56 } 57 58 int main() { 59 scanf("%d%d", &n, &m); 60 for(int i = 1, x, y, z; i <= n; i++) { 61 scanf("%d%d%d", &x, &y, &z); 62 d[x].push_back(z); 63 d[y + 1].push_back(-z); 64 } 65 66 // prework 67 for(int i = 1; i <= m; i++) { 68 if(!d[i].size()) { 69 rt[i] = rt[i - 1]; 70 continue; 71 } 72 for(int j = 0; j < d[i].size(); j++) { 73 // d[i][j] 74 if(d[i][j] > 0) { 75 insert(rt[i - 1], rt[i], d[i][j], 1, 1, lm); 76 } 77 else { 78 insert(rt[i - 1], rt[i], -d[i][j], -1, 1, lm); 79 } 80 } 81 } 82 83 LL lastans = 1; 84 for(int i = 1, t, y, z, w; i <= m; i++) { 85 scanf("%d%d%d%d", &t, &y, &z, &w); 86 lastans %= w; 87 y %= w; 88 int k = (lastans * y + z) % w + 1; 89 lastans = ask(k, 1, lm, rt[t]); 90 printf("%lld\n", lastans); 91 } 92 93 return 0; 94 }