标签:ros ret else 等于 printf pos void can sqrt
分块初始化:
int a[50005];//原始序列 int l[2000];//第i个块的左区间端点 int r[2000];//第i个块的右区间端点 int pos[50005];//第i个点属于第几个块 int n; scanf("%d",&n); int dis=sqrt(n);//每一块的大小 int num=ceil(n*1.0/dis);//分块数目 for(int i=1;i<=num;i++) { l[i]=(i-1)*dis+1;//第i个块的左区间端点 r[i]=i*dis;//第i个块的右区间端点 } r[num]=n;//最后一个块的右端点最大等于n for(int i=1;i<=n;i++) { scanf("%d",&a[i]); pos[i]=(i-1)/dis+1;//第i个数属于第几个块 }
题意:支持区间加,求区间小于c*c的个数
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const int inf=0x3f3f3f3f; const ll INF=1e18; const int M=5e4+4; int a[M],b[M],pos[M],l[M],r[M],lz[M]; void init(int n){ int dis=sqrt(n); int num=ceil(n*1.0/dis); for(int i=1;i<=num;i++){ l[i]=(i-1)*dis+1; r[i]=i*dis; } r[num]=n; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); pos[i]=(i-1)/dis+1; b[i]=a[i]; } for(int i=1;i<=num;i++) sort(b+l[i],b+r[i]+1); } void add(int L,int R,int v){ int posl=pos[L],posr=pos[R]; if(posl==posr){ for(int i=L;i<=R;i++) a[i]+=v; for(int i=l[posl];i<=r[posl];i++) b[i]=a[i]; sort(b+l[posl],b+r[posl]+1); } else{ ///left for(int i=L;i<=r[posl];i++) a[i]+=v; for(int i=l[posl];i<=r[posl];i++) b[i]=a[i]; sort(b+l[posl],b+r[posl]+1); ///mid for(int i=posl+1;i<posr;i++) lz[i]+=v; ///right for(int i=l[posr];i<=R;i++) a[i]+=v; for(int i=l[posr];i<=r[posr];i++) b[i]=a[i]; sort(b+l[posr],b+r[posr]+1); } } int query(int L,int R,int c){ int posl=pos[L],posr=pos[R]; int cnt=0; if(posl==posr){ for(int i=L;i<=R;i++) if(a[i]<c-lz[posl]) cnt++; return cnt; } ///left for(int i=L;i<=r[posl];i++) if(a[i]<c-lz[posl]) cnt++; ///right for(int i=l[posr];i<=R;i++) if(a[i]<c-lz[posr]) cnt++; ///mid for(int i=posl+1;i<posr;i++) cnt+=lower_bound(b+l[i],b+r[i]+1,c-lz[i])-(b+l[i]); return cnt; } int main(){ int n; scanf("%d",&n); init(n); for(int i=1;i<=n;i++){ int op,x,y,c; scanf("%d%d%d%d",&op,&x,&y,&c); if(op==0) add(x,y,c); else printf("%d\n",query(x,y,c*c)); } return 0; }
标签:ros ret else 等于 printf pos void can sqrt
原文地址:https://www.cnblogs.com/starve/p/12830063.html