數列分塊入門 1
阿新 • • 發佈:2018-04-30
輸入一個數 std -s space head fan pad baseline sin
題目描述
給出一個長為
輸入格式
第一行輸入一個數字
第二行輸入
接下來輸入
若
若
輸出格式
對於每次詢問,輸出一行一個數字表示答案。
思路:
最簡單的數列分塊
先明確一波分塊的概念:
將一個長為n數列拆成k塊兒(一般k=sqrt(n));
然後對區間的修改變為對完整塊的修改和對區間兩端不完整塊的暴力
那如何描述對區間的修改和查詢呢?
lazy大法好!!
建一個標記數組,存儲對整個區間的修改
最後輸出標記數組與原值的和即可
代碼:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int x[50005],sy[50005],fk[50005],n,opt,l,r,c,a,b,d,dx,cnt,bnt; int main() { // freopen("a1.in","r",stdin); // freopen("1.out","w",stdout); cin>>n; dx=sqrt(n); bnt=1; for(a=1;a<=n;a++) { scanf("%d",&x[a]); sy[a]=(a-1)/dx+1; } for(a=1;a<=n;a++) { scanf("%d%d%d%d",&opt,&l,&r,&c); if(opt==1) { printf("%d\n",x[r]+fk[sy[r]]); } else { if(sy[l]==sy[r]) { for(b=l;b<=r;b++) { x[b]+=c; } continue; } int lf,ri; lf=sy[l]; ri=sy[r]; for(b=l;b<=lf*dx;b++) { x[b]+=c; } for(b=(ri-1)*dx+1;b<=r;b++) { x[b]+=c; } for(b=lf+1;b<=ri-1;b++) { fk[b]+=c; } } } }
數列分塊入門 1