分块练习 C

来源:互联网 发布:神秀和慧能 知乎 编辑:程序博客网 时间:2024/05/21 13:56
#include<cstdio>#include<cmath>#include<algorithm>#include<iostream>using namespace std;const int maxn = 100005;int n,r[maxn],l[maxn],num,block;int d[maxn],ad[maxn],a[maxn];int h,w,belong[maxn];int loger(int l,int r,int x){while(r - l > 1){int mid = (l + r)>>1;if(a[mid] >= x) r = mid;else l = mid;}if(a[l] >= x)return 0;return l;}void build(){block = sqrt(n);num = n/block; if(n%block) num++;for(int i = 1; i <= num; i++){l[i] = (i-1)*block+1;r[i] = i*block;}r[num] = n;for(int i = 1; i <= n; i++){belong[i] = (i-1)/block+1;}for(int i = 1; i <= num; i++){sort(a+l[i],a+r[i]+1);}}void add(int x,int y,int c){h = belong[x]; w = belong[y];if(h == w){for(int i = x; i <= y; i++) d[i] += c;for(int i = l[h]; i <= r[h]; i++) a[i] = d[i];sort(a+l[h],a+r[h]+1);}else if(h != w){for(int i = x; i <= r[h]; i++) d[i] += c;for(int i = l[h]; i <= r[h]; i++) a[i] = d[i];sort(a+l[h],a+r[h]+1);for(int i = l[w]; i <= y; i++) d[i] += c;for(int i = l[w]; i <= r[w]; i++) a[i] = d[i];sort(a+l[w],a+r[w]+1);}for(int i=h+1; i <= w-1; i++) ad[i] += c;}int query(int x,int y,int c){int ans = -1,top = 0;h = belong[x]; w = belong[y];if(h == w){for(int i = x; i <= y; i++) if(d[i] < c-ad[h])ans = max(ans,d[i]+ad[h]);}else if(h != w){for(int i = x; i <= r[h]; i++) if(d[i] < c-ad[h])ans = max(ans,d[i]+ad[h]);for(int i = l[w]; i <= y; i++) if(d[i] < c-ad[w])ans = max(ans,d[i]+ad[w]);}for(int i=h+1; i <= w-1; i++){top = loger(l[i],r[i]+1,c-ad[i]);ans = max(ans,top?a[top]+ad[i]:-1);}return ans;}int main(){scanf("%d",&n);for(int i = 1; i <= n; i++){scanf("%d",&a[i]);d[i] = a[i];}build();int f,a,b,c;for(int i = 1; i <= n; i++){scanf("%d%d%d%d",&f,&a,&b,&c);if(f==0) add(a,b,c);else printf("%d\n",query(a,b,c));}return 0;}

#include<map>#include<set>#include<cmath>#include<stack>#include<queue>#include<cstdio>#include<vector>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#define mod 998244353#define pi acos(-1)#define inf 0x7fffffff#define ll long longusing namespace std;ll read(){    ll x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int n,blo;int v[100005],bl[100005],atag[100005];set<int>st[105];void add(int a,int b,int c){    for(int i=a;i<=min(bl[a]*blo,b);i++)    {        st[bl[a]].erase(v[i]);        v[i]+=c;        st[bl[a]].insert(v[i]);    }    if(bl[a]!=bl[b])    {        for(int i=(bl[b]-1)*blo+1;i<=b;i++)        {            st[bl[b]].erase(v[i]);            v[i]+=c;            st[bl[b]].insert(v[i]);        }    }    for(int i=bl[a]+1;i<=bl[b]-1;i++)        atag[i]+=c;}int query(int a,int b,int c){    int ans=-1;    for(int i=a;i<=min(bl[a]*blo,b);i++)    {        int val=v[i]+atag[bl[a]];        if(val<c)ans=max(val,ans);    }    if(bl[a]!=bl[b])                for(int i=(bl[b]-1)*blo+1;i<=b;i++)                {            int val=v[i]+atag[bl[b]];            if(val<c)ans=max(val,ans);        }    for(int i=bl[a]+1;i<=bl[b]-1;i++)    {        int x=c-atag[i];        set<int>::iterator it=st[i].lower_bound(x);        if(it==st[i].begin())continue;        --it;        ans=max(ans,*it+atag[i]);    }    return ans;}int main(){    n=read();blo=1000;    for(int i=1;i<=n;i++)v[i]=read();    for(int i=1;i<=n;i++)    {        bl[i]=(i-1)/blo+1;        st[bl[i]].insert(v[i]);    }    for(int i=1;i<=n;i++)    {        int f=read(),a=read(),b=read(),c=read();        if(f==0)add(a,b,c);        if(f==1)printf("%d\n",query(a,b,c));    }    return 0;}

0 0