LibreOJ 6277 數列分塊入門 1(分塊區修,單點查詢)
阿新 • • 發佈:2020-07-21
解題思路
分塊模版|
程式碼
const int maxn = 5e4+10; int n,sz,num,a[maxn],ls[maxn],rs[maxn],belong[maxn],lazy[maxn]; void build() { num = (n+sz-1)/sz; //分塊大小 for (int i = 1; i<=num; ++i) { ls[i] = (i-1)*sz+1, rs[i] = i*sz; //每個塊左右邊界 } rs[num] = n; for (int i = 1; i<=n; ++i) belong[i] = (i-1)/sz+1; //每個元素所屬塊 } void update(int l, int r, int c) { if (belong[l]==belong[r]) { //同一個塊直接暴力 for (int i = l; i<=r; ++i) a[i] += c; return; } //不同塊左右暴力,中間塊打標記 for (int i = belong[l]+1; i<belong[r]; ++i) lazy[i] += c; for (int i = l; i<=rs[belong[l]]; ++i) a[i] += c; for (int i = ls[belong[r]]; i<=r; ++i) a[i] += c; } int find(int p) { if (lazy[belong[p]]) { //塊內標記下傳 for (int i = ls[belong[p]]; i<=rs[belong[p]]; ++i) a[i] += lazy[belong[p]]; lazy[belong[p]] = 0; } return a[p]; } int main() { scanf("%d",&n); for (int i = 1; i<=n; ++i) scanf("%d",&a[i]); sz = sqrt(n); build(); for (int i = 1,op,l,r,c; i<=n; ++i) { scanf("%d%d%d%d",&op,&l,&r,&c); if (!op) update(l,r,c); else printf("%d\n",find(r)); } return 0; }