1. 程式人生 > >[Luogu] 教主的魔法

[Luogu] 教主的魔法

一個 alc ret style pre min calc cin fin

https://www.luogu.org/problemnew/show/P2801

分塊

對於每一塊進行排序存儲在另一個數組中

二分查詢

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>

using namespace std;

#define gc getchar()

const int N = 1e6 + 10;
const int M = 1e3 + 10;

int A[N], B[N], Pos[N], Add[M];
int n, Q, cnt, block; inline int read(){ int x = 0, f = 1; char c = gc; while(c < 0 || c > 9) {if(c == -) f = -1; c = gc;} while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = gc; return x * f; } inline void Sort(int x){ int l = (x - 1) * block + 1
, r = min(n, x * block); for(int i = l; i <= r; i ++) B[i] = A[i]; sort(B + l, B + r + 1); } inline void Sec_G(int x, int y, int z){ if(Pos[x] == Pos[y]){for(int i = x; i <= y; i ++) A[i] += z; Sort(Pos[x]); return ;} else { for(int i = x; i <= Pos[x] * block; i ++) A[i] += z;
for(int i = (Pos[y] - 1) * block + 1; i <= y; i ++) A[i] += z; Sort(Pos[x]); Sort(Pos[y]); } for(int i = Pos[x] + 1; i < Pos[y]; i ++) Add[i] += z; } inline int to_calc(int x, int num){ int l = (x - 1) * block, r = min(x * block, n), last = r, ans; while(l <= r){ int mid = (l + r) >> 1; if(B[mid] < num) ans = mid, l = mid + 1; else r = mid - 1; } return last - ans + 1; } inline int Sec_A(int x, int y, int z){ int answer(0); if(Pos[x] == Pos[y]){for(int i = x; i <= y; i ++) if(A[i] + Add[Pos[x]] >= z) answer ++; return answer;} else { for(int i = x; i <= Pos[x] * block; i ++) if(A[i] + Add[Pos[x]] >= z) answer ++; for(int i = (Pos[y] - 1) * block + 1; i <= y; i ++) if(A[i] + Add[Pos[y]] >= z) answer ++; } for(int i = Pos[x] + 1; i < Pos[y]; i ++) answer += to_calc(i, z - Add[i]); return answer; } int main() { freopen("gg.in", "r", stdin); n = read(); Q = read(); block = sqrt(n); for(int i = 1; i <= n; i ++) A[i] = read(); for(int i = 1; i <= n; i ++) Pos[i] = (i - 1) / block + 1; for(int i = 1; i <= n; i ++) Sort(i); if(n % block) cnt = n / block + 1; else cnt = n / block; while(Q --){ string s; cin >> s; int x = read(), y = read(), z = read(); if(s[0] == A) Sec_G(x, y, z); else cout << Sec_A(x, y, z) << endl; } return 0; } /* 5 3 1 2 3 4 5 A 1 5 4 M 3 5 1 A 1 5 4 */

[Luogu] 教主的魔法