//数列分块练习2 #include<iostream> #include<algorithm> #include<vector> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #define ll long long #define N 10000009 using namespace std; vector<ll> a[2600]; ll v[N],tag[N]; int bl[N]; int n,blo; ll read() { char ch=getchar();ll ret=0,f=1; while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){ret=ret*10+ch-'0';ch=getchar();} return f*ret; } void reinit(int x) { a[x].clear(); for (int i=(x-1)*blo+1;i<=min(n,x*blo);i++) a[x].push_back(v[i]); sort(a[x].begin(),a[x].end()); } void change(int l,int r,ll d) { for (int i=l;i<=min(bl[l]*blo,r);i++) v[i]+=d;reinit(bl[l]); if (bl[l]!=bl[r]) {for (int i=(bl[r]-1)*blo+1;i<=r;i++) v[i]+=d;reinit(bl[r]);} for (int i=bl[l]+1;i<=bl[r]-1;i++) tag[i]+=d; } int query(int l,int r,ll c) { int ret=0; for (int i=l;i<=min(bl[l]*blo,r);i++) if (v[i]+tag[bl[l]]<c) ret++; if (bl[l]!=bl[r]) for (int i=(bl[r]-1)*blo+1;i<=r;i++) if (v[i]+tag[bl[r]]<c) ret++; for (int i=bl[l]+1;i<=bl[r]-1;i++) { int x=c-tag[i]; ret+=lower_bound(a[i].begin(),a[i].end(),x)-a[i].begin(); } return ret; } int main() { n=read();blo=sqrt(n); for (int i=1;i<=n;i++) v[i]=read(); for (int i=1;i<=n;i++) { bl[i]=(i-1)/blo+1; a[bl[i]].push_back(v[i]); } for (int i=1;i<=bl[n];i++) sort(a[i].begin(),a[i].end()); for (int i=1;i<=n;i++) { int opt=read(),l=read(),r=read();ll d=read(); if (opt==0) change(l,r,d); else printf("%d\n",query(l,r,d*d)); } return 0; }
【loj6278】数列分块入门 2
猜你喜欢
转载自blog.csdn.net/Dadatu_Zhao/article/details/80559204
今日推荐
周排行