Codechef :Chef and ChuruFNCS(分块)

xiaoxiao2021-07-05  263

传送门

题解: 随便分一下块就好了。。

#include <bits/stdc++.h> using namespace std; typedef unsigned long long LL; const int RLEN=1<<18|1; inline char nc() { static char ibuf[RLEN],*ib,*ob; (ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin)); return (ib==ob) ? -1 : *ib++; } inline int rd() { char ch=nc(); int i=0,f=1; while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();} while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();} return i*f; } inline void W(LL x) { static int buf[50]; if(!x) {putchar('0'); return;} if(x<0) {putchar('-'); x=-x;} while(x) {buf[++buf[0]]=x%10; x/=10;} while(buf[0]) {putchar(buf[buf[0]--]+'0');} } const int N=1e5+50, S=334, H=N/S+5; int n,m,a[N],bl[N],bg[H],ed[H],h; struct BL { LL s[N],tag[H]; inline void add(int pos,LL val) { int t=bl[pos]; for(int i=t+1;i<=h;i++) tag[i]+=val; for(int i=pos;i<=ed[t];i++) s[i]+=val; } inline LL ask(int pos) {return s[pos]+tag[bl[pos]];} inline LL ask(int l,int r) {return ask(r)-ask(l-1);} } block; int li[N],ri[N]; LL num[H][N]; LL sum[H]; inline void init() { for(int i=1,j;i<=n;) { j=min(i+S-1,n); ++h; bg[h]=i; ed[h]=j; while(i<=j) bl[i++]=h; } } inline LL ask(int l,int r) { LL val=0; if(r-l+1<=2*S) { for(int i=l;i<=r;i++) val+=block.ask(li[i],ri[i]); } else { int L=bl[l]+1, R=bl[r]-1; for(int i=L;i<=R;i++) val+=sum[i]; for(int i=l;i<bg[L];i++) val+=block.ask(li[i],ri[i]); for(int i=r;i>ed[R];i--) val+=block.ask(li[i],ri[i]); } return val; } int main() { n=rd(); init(); for(int i=1;i<=n;i++) block.s[i]=(a[i]=rd())+block.s[i-1]; for(int i=1;i<=n;i++) li[i]=rd(), ri[i]=rd(); for(int i=1;i<=h;i++) { for(int j=bg[i];j<=ed[i];j++) sum[i]+=block.ask(li[j],ri[j]), num[i][li[j]]++, num[i][ri[j]+1]--; for(int j=1;j<=n;j++) num[i][j]+=num[i][j-1]; } m=rd(); for(int i=1;i<=m;i++) { int op=rd(), l=rd(), r=rd(); if(op==1) { LL det=r-a[l]; block.add(l,det); for(int j=1;j<=h;j++) sum[j]+=num[j][l]*det; a[l]+=det; } else { W(ask(l,r)); putchar('\n'); } } }
转载请注明原文地址: https://www.6miu.com/read-4821415.html

最新回复(0)