数列分块1
//分块后在块内二分,两边暴力处理 #include<cstdio> #include<cctype> #include<cmath> #include<algorithm> using namespace std; int n,block,tot,belong[50002],r[250],a[50002],b[50002],ad[250]; inline void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } void reset(int whic){ for(int i=r[whic-1]+1;i<=r[whic];i++)b[i]=a[i]; sort(b+r[whic-1]+1,b+r[whic]); } void add(int x,int y,int c){ int lb=belong[x],rb=belong[y]; if(lb==rb){ for(register int i=x;i<=y;i++)a[i]+=c; reset(lb); return; } if(x%block!=1){ for(register int i=x;i<=r[belong[x]];i++)a[i]+=c; reset(lb); lb++; } if(y%block>0){ for(register int i=r[belong[y]-1]+1;i<=y;i++)a[i]+=c; reset(rb); rb--; } for(register int i=lb;i<=rb;i++)ad[i]+=c; } int query(int x,int y,int c){ int lb=belong[x],rb=belong[y]; int ans=0; if(lb==rb){ for(register int i=x;i<=y;i++)if(a[i]+ad[belong[x]]<c)ans++; return ans; } if(x%block!=1){ for(register int i=x;i<=r[belong[x]];i++)if(a[i]+ad[belong[x]]<c)ans++; lb++; } if(y%block>0){ for(register int i=r[belong[y]-1]+1;i<=y;i++) if(a[i]+ad[belong[y]]<c)ans++; rb--; } for(int i=lb;i<=rb;i++){ ans=ans+lower_bound(b+r[i-1]+1,b+r[i],c-ad[i])-b-r[i-1]-1;//被lower_bound处理卡了两天。。。 if(c-ad[i]>b[r[i]])ans++;//因为若数组最后一个数仍小于寻找的数,返回的是最后一个位置,未将最后一个数算进去 }return ans; } inline void putans(int x){ if(x>=10)putans(x/10);putchar('0'+x%10);return; } int main(){ read(n);block=sqrt(n); for(register int i=1;i<=n;i++){ read(a[i]); belong[i]=tot; if(i%block==1){r[tot]=i-1;belong[i]=++tot;} } b[0]=a[0]=-1000000; r[tot]=n; for(int i=1;i<=tot;i++)reset(i); for(register int i=1;i<=n;i++){ int opt,x,y,c; read(opt);read(x);read(y);read(c); if(opt==0)add(x,y,c);else printf("%d\n",query(x,y,c*c)); } }
数列分块2
#include<cstdio> #include<algorithm> #include<cctype> #include<set> #include<cmath> using namespace std; typedef long long ll; int n,block,tot,a[100002],belong[100002],r[350],ad[350]; set<int>st[350]; inline void read(int&x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } void add(int x,int y,int c){ int lb=belong[x],rb=belong[y]; if(lb==rb){ for(int i=x;i<=y;i++){ st[lb].erase(a[i]);a[i]+=c;st[lb].insert(a[i]); } return; } if(x%block!=1){ for(int i=x;i<=r[lb];i++){ st[lb].erase(a[i]);a[i]+=c;st[lb].insert(a[i]); } lb++; } if(y%block>0){ for(int i=r[rb-1]+1;i<=y;i++){ st[rb].erase(a[i]);a[i]+=c;st[rb].insert(a[i]); } rb--; } for(int i=lb;i<=rb;i++)ad[i]+=c; } int query(int x,int y,int c){ int ans=-1,lb=belong[x],rb=belong[y]; if(lb==rb){ for(int i=x;i<=y;i++)if(a[i]+ad[lb]<c)ans=max(ans,a[i]+ad[lb]); return ans; } if(x%block!=1){ for(int i=x;i<=r[lb];i++)if(a[i]+ad[lb]<c)ans=max(ans,a[i]+ad[lb]); lb++; } if(y%block>0){ for(int i=r[rb-1]+1;i<=y;i++)if(a[i]+ad[rb]<c)ans=max(ans,a[i]+ad[rb]); rb--; } for(int i=lb;i<=rb;i++){ set<int>::iterator it=st[i].lower_bound(c-ad[i]); if(it!=st[i].begin()){ it--; ans=max(ans,*it+ad[i]); } } return ans; } int main(){ read(n);block=sqrt(n); for(int i=1;i<=n;i++){ read(a[i]); if(i%block==1)r[tot]=tot*block,belong[i]=++tot;else belong[i]=tot; st[belong[i]].insert(a[i]); } r[tot]=n; for(int i=1;i<=n;i++){ int opt,x,y,c; read(opt);read(x);read(y);read(c); if(opt==0)add(x,y,c);else printf("%d\n",query(x,y,c)); } }
数列分块3
#include<cstdio> #include<cctype> #include<cmath> using namespace std; int n,block,tot; long long a[50002],belong[50002],r[250],ad[250]; long long sum[250]; inline void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } inline void read(long long &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } inline void add(int x,int y,int c){ int lb=belong[x],rb=belong[y]; if(lb==rb){ for(int i=x;i<=y;i++)a[i]+=c; sum[lb]=sum[lb]+(y-x+1)*c; return; } if(x%block!=1){ for(int i=x;i<=r[lb];i++)a[i]+=c; sum[lb]=sum[lb]+(r[lb]-x+1)*c; lb++; } if(y%block>0){ for(int i=r[rb-1]+1;i<=y;i++)a[i]+=c; sum[rb]=sum[rb]+(y-r[rb-1])*c; rb--; } for(int i=lb;i<=rb;i++)ad[i]+=c; } inline int query(int x,int y,int c){ long long ans=0; int lb=belong[x],rb=belong[y]; if(lb==rb){ ans=(y-x+1)*ad[lb]%(c+1); for(int i=x;i<=y;i++)ans=(ans+a[i])%(c+1); return ans; } if(x%block!=1){ for(int i=x;i<=r[lb];i++)ans=(ans+a[i])%(c+1); ans=(ans+(r[lb]-x+1)*ad[lb]%(c+1))%(c+1); lb++; } if(y%block>0){ for(int i=r[rb-1]+1;i<=y;i++)ans=(ans+a[i])%(c+1); ans=(ans+(y-r[rb-1])*ad[rb]%(c+1))%(c+1); rb--; } for(int i=lb;i<=rb;i++)ans=(ans+sum[i]+ad[i]*(r[i]-r[i-1])%(c+1))%(c+1); return ans; } int main(){ read(n);block=sqrt(n); for(int i=1;i<=n;i++){ read(a[i]); if(i%block==1){r[tot]=i-1;belong[i]=++tot;}else belong[i]=tot; sum[belong[i]]+=a[i]; } for(int i=1;i<=n;i++){ int opt,x,y,c; read(opt);read(x);read(y);read(c); if(opt==0)add(x,y,c);else printf("%d\n",query(x,y,c)); } }