CodeForces

tle了好几天= =提交20+次,我都怕cf说我恶意卡测评。。。

题意:一个数组,两种操作,一种l到r加一个值,还有一种查询整个数组里距离最远的某个数的距离

题解:分块,用vector+lowbound,加法用lazy标记,查询用lowbound,复杂度O(n*sqrt(n)*log(sqrt(n)))

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-7;
const int N=500000+10,maxn=sqrt(N)+10,inf=0x3f3f3f;

int n,m,block,num;
int l[maxn],r[maxn],belong[N];
ll a[N],lazy[maxn];
vector<int>v[N];
void build()
{
    block=(int)sqrt(n+0.5);
    num=n/block;
    if(n%block)num++;
    for(int i=1;i<=n;i++)
    {
        belong[i]=(i-1)/block+1;
        v[(i-1)/block+1].pb(a[i]);
    }
    for(int i=1;i<=num;i++)
    {
        sort(v[i].begin(),v[i].end());
        l[i]=(i-1)*block+1,r[i]=i*block;
    }
    r[num]=n;
}
void rebuild(int id)
{
    v[id].clear();
    for(int i=l[id];i<=r[id];i++)
        if(a[i]+lazy[id]<=1e9)
            v[id].pb(a[i]);
    sort(v[id].begin(),v[id].end());
}
void update(int x,int y,ll z)
{
    int idx=belong[x],idy=belong[y];
    if(idx==idy)
    {
        for(int i=x;i<=y;i++)
            a[i]+=z;
        rebuild(idx);
    }
    else
    {
        for(int i=x;i<=r[idx];i++)
            a[i]+=z;
        for(int i=l[idy];i<=y;i++)
            a[i]+=z;
        rebuild(idx);
        rebuild(idy);
        for(int i=idx+1;i<idy;i++)
            lazy[i]+=z;
    }
}
int query(int x)
{
    int p=0;
    for(int i=1;i<=num;i++)
    {
        int s=lower_bound(v[i].begin(),v[i].end(),x-lazy[i])-v[i].begin();
        if(s!=v[i].size()&&v[i][s]==x-lazy[i])
        {
            p=i;
            break;
        }
    }
    if(p==0)return -1;
    int ans1=-1,ans2=-1;
    for(int i=l[p];i<=r[p];i++)
    {
        if(a[i]+lazy[p]==x)
        {
            ans1=i;
            break;
        }
    }
    for(int i=num;i>=1;i--)
    {
        int s=lower_bound(v[i].begin(),v[i].end(),x-lazy[i])-v[i].begin();
        if(s!=v[i].size()&&v[i][s]==x-lazy[i])
        {
            p=i;
            break;
        }
    }
    for(int i=r[p];i>=l[p];i--)
    {
        if(a[i]+lazy[p]==x)
        {
            ans2=i;
            break;
        }
    }
    return ans2-ans1;
}
void debug()
{
    for(int i=1;i<=n;i++)
        printf("%lld ",a[i]+lazy[belong[i]]);
    puts("");
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    build();
    while(m--)
    {
        int x,y;
        ll z;
        scanf("%d",&x);
        if(x==1)
        {
            scanf("%d%d%lld",&x,&y,&z);
            update(x,y,z);
        }
        else
        {
            scanf("%d",&x);
            printf("%d
",query(x));
        }
    }
    return 0;
}
/********************

********************/
View Code
原文地址:https://www.cnblogs.com/acjiumeng/p/7677310.html