题解——loj6278 数列分块入门2 (分块)
查询小于k的值
注意lower_bound一定要减去查找的起始位置得到正确的位置
调了快两天
淦
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; int a[50501],b[50501],belong[50501],tag[50501],num,sz,n; void calbe(int n){ for(int i=1;i<=n;i++){ belong[i]=(i-1)/sz+1; } } void reset(int l,int r){ for(int i=l;i<=r;i++) b[i]=a[i]; sort(b+l,b+r+1); } void update(int l,int r,int w){ int xl=belong[l]; int xr=belong[r]; for(int i=l;i<=min(r,sz*xl);i++){ a[i]+=w; } reset((xl-1)*sz+1,min(xl*sz,n)); if(xl!=xr){ for(int i=(xr-1)*sz+1;i<=r;i++) a[i]+=w; reset((xr-1)*sz+1,min(xr*sz,n)); } for(int i=xl+1;i<=xr-1;i++) tag[i]+=w; } int query(int l,int r,int w){ // printf("qw=%d\n",w); int xl=belong[l]; int xr=belong[r]; // printf("ln=%d || rn=%d\n",xl,xr); int ans=0; for(int i=l;i<=min(r,sz*xl);i++){ // printf("tag=%d || qsw=%d\n",tag[xl],w-tag[xl]); if(a[i]<w-tag[xl]){ ans++; // printf("a[%d] = %d || w=%d ||tag=%d\n",i,a[i],w,tag[xl]); } } if(xl!=xr){ for(int i=(xr-1)*sz+1;i<=r;i++){ // printf("tag=%d || qsw=%d\n",tag[xr],w-tag[xr]); if(a[i]<w-tag[xr]){ ans++; // printf("a[%d] = %d || w=%d ||tag=%d\n",i,a[i],w,tag[xl]); } } } for(int i=xl+1;i<=xr-1;i++){ int pos = lower_bound(b+sz*(i-1)+1,b+sz*i+1,w-tag[i])-(b+(i-1)*sz+1); // printf("pos/%d:%d st=%d \n",i,pos,(i-1)*sz+1); ans+=pos; } return ans; } int main(){ scanf("%d",&n); sz=sqrt(n); calbe(n); num=n/sz; if(n%sz) num++; // printf("sz=%d\n",sz); // for(int i=1;i<=n;i++) // printf("%d ",belong[i]); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=num;i++){ reset((i-1)*sz+1,min(sz*i,n)); } // for(int i=1;i<=num;i++){ // printf("block:%d\nB: ",i); // for(int j=(i-1)*sz+1;j<=i*sz;j++) // printf("%d ",b[j]+tag[i]); // printf("\nA: "); // for(int j=(i-1)*sz+1;j<=i*sz;j++) // printf("%d ",a[j]+tag[i]); // printf("\n\n"); // } for(int i=1;i<=n;i++){ int opt,l,r,c; scanf("%d %d %d %d",&opt,&l,&r,&c); if(opt==0){ update(l,r,c); // for(int i=1;i<=num;i++){ // printf("block:%d tag:%d\nB: ",i,tag[i]); // for(int j=(i-1)*sz+1;j<=i*sz;j++) // printf("%d ",b[j]+tag[i]); // printf("\nA: "); // for(int j=(i-1)*sz+1;j<=i*sz;j++) // printf("%d ",a[j]+tag[i]); // printf("\n\n"); // } } else{ printf("%d\n",query(l,r,c*c)); } } return 0; }