• Codeforces Round #307 (Div. 2) E. GukiZ and GukiZiana 分块


    E. GukiZ and GukiZiana

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

    http://codeforces.com/contest/551/problem/E

    Description

    Professor GukiZ was playing with arrays again and accidentally discovered new function, which he called GukiZiana. For given array a, indexed with integers from 1 to n, and number y, GukiZiana(a, y) represents maximum value of j - i, such that aj = ai = y. If there is no y as an element in a, then GukiZiana(a, y) is equal to  - 1. GukiZ also prepared a problem for you. This time, you have two types of queries:

        First type has form 1 l r x and asks you to increase values of all ai such that l ≤ i ≤ r by the non-negative integer x.
        Second type has form 2 y and asks you to find value of GukiZiana(a, y).

    For each query of type 2, print the answer and make GukiZ happy!

    Input

    The first line contains two integers n, q (1 ≤ n ≤ 5 * 105, 1 ≤ q ≤ 5 * 104), size of array a, and the number of queries.

    The second line contains n integers a1, a2, ... an (1 ≤ ai ≤ 109), forming an array a.

    Each of next q lines contain either four or two numbers, as described in statement:

    If line starts with 1, then the query looks like 1 l r x (1 ≤ l ≤ r ≤ n, 0 ≤ x ≤ 109), first type query.

    If line starts with 2, then th query looks like 2 y (1 ≤ y ≤ 109), second type query.

    Output

    For each query of type 2, print the value of GukiZiana(a, y), for y value for that query.

    Sample Input

    4 3
    1 2 3 4
    1 1 2 1
    1 1 1 1
    2 3

    Sample Output

    2

    HINT

    题意

    一堆数,俩操作

    [l,r]区间的数都加 v

    查询最大的j-i,要求满足a[j]=a[i]=v

    题解:

    时间10s,这就是明摆着告诉我们这道题是分块,然后我们就分块乱搞就好了……

    二分写挂的都是傻逼(没错就是我!

    代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define test freopen("test.txt","r",stdin)  
    #define maxn 2000001
    #define mod 10007
    #define eps 1e-9
    const int inf=0x3f3f3f3f;
    const ll infll = 0x3f3f3f3f3f3f3f3fLL;
    inline 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;
    }
    //**************************************************************************************
    
    ll n,q,m,block;
    ll a[1000001],b[1000001],pos[1000001],add[1000001];
    void reset(ll x)
    {
        ll l=(x-1)*block+1,r=min(x*block,n);
        for(ll i=l;i<=r;i++)
            b[i]=a[i];
        sort(b+l,b+r+1);
    }
    ll find(ll x,ll v)
    {
        ll l=(x-1)*block+1,r=min(x*block,n);
        ll last=r;
        while(l<r)
        {
            ll mid=(l+r)>>1;
            if(b[mid]<v)l=mid+1;
            else
                r=mid;
            if(b[mid]==v)
                return 1;
        }
        if(b[l]==v||b[r]==v)
            return 1;
        return 0;
    }
    void update(ll x,ll y,ll v)
    {
        if(pos[x]==pos[y])
        {
            for(int i=x;i<=y;i++)a[i]=a[i]+v;
        }
        else 
        {
            for(int i=x;i<=pos[x]*block;i++)a[i]=a[i]+v;
            for(int i=(pos[y]-1)*block+1;i<=y;i++)a[i]=a[i]+v;
        }
        reset(pos[x]);reset(pos[y]);
        for(int i=pos[x]+1;i<pos[y];i++)
           add[i]+=v;
    }
    ll query(ll x,ll y,ll v)
    {
        ll sum=0;
        if(pos[x]==pos[y])
        {
            for(int i=x;i<=y;i++)if(a[i]+add[pos[i]]==v)sum++;
        }
        else 
        {
            for(int i=x;i<=pos[x]*block;i++)
                if(a[i]+add[pos[i]]==v)sum++;
            for(int i=(pos[y]-1)*block+1;i<=y;i++)
                if(a[i]+add[pos[i]]==v)sum++;
        }
        for(int i=pos[x]+1;i<pos[y];i++)
            sum+=find(i,v-add[i]);
        
        //cout<<sum<<endl;
        return sum;
    }
    ll deall(ll x,ll y,ll v)
    {
        ll sum=0;
        if(pos[x]==pos[y])
        {
            for(int i=x;i<=y;i++)if(a[i]+add[pos[i]]==v)return i;
        }
        else 
        {
            for(int i=x;i<=pos[x]*block;i++)
                if(a[i]+add[pos[i]]==v)return i;
            for(int i=pos[x]+1;i<pos[y];i++)
            {
                int d=find(i,v-add[i]);
                if(d>0)
                {
                    for(int j=i*block-block+1;j<=i*block;j++)
                        if(a[j]+add[pos[j]]==v)
                            return j;
                }
            }
            for(int i=(pos[y]-1)*block+1;i<=y;i++)
                if(a[i]+add[pos[i]]==v)return i;
        }
    }
    ll dealr(ll x,ll y,ll v)
    {
        ll sum=0;
        if(pos[x]==pos[y])
        {
            for(int i=y;i>=x;i--)if(a[i]+add[pos[i]]==v)return i;
        }
        else 
        {
            for(int i=y;i>=(pos[y]-1)*block+1;i--)
                if(a[i]+add[pos[i]]==v)
                    return i;
    
            for(int i=pos[y];i>=pos[x]+1;i--)
            {
                int d=find(i,v-add[i]);
                if(d>0)
                {
                    for(int j=i*block;j>=i*block-block;j--)
                        if(a[j]+add[pos[j]]==v)
                            return j;
                }
            }
            for(int i=pos[x]*block;i>=x;i--)
                if(a[i]+add[pos[i]]==v)return i;
    
        }
    }
    int ask(ll cc)
    {
        int aa=query(1,n,cc);
        if(aa==0)
            return -1;
        return dealr(1,n,cc)-deall(1,n,cc);
    }
    int main()
    {
        //test;
        n=read(),q=read();
        block=int(sqrt(n));
        for(int i=1;i<=n;i++)
        {
            a[i]=read();
            pos[i]=(i-1)/block+1;
            b[i]=a[i];
        }
        int x,y,v,ch;
        if(n%block)m=n/block+1;
        else m=n/block;
        for(int i=1;i<=m;i++)reset(i);
        for(int i=1;i<=q;i++)
        {
            ch=read();
            if(ch==1)
            {
                x=read(),y=read(),v=read();
                update(x,y,v);
            }
            else
            {
                int p;
                p=read();
                printf("%d
    ",ask(p));
            }
        }
        return 0;
    }
  • 相关阅读:
    测试脚本
    浅谈优化SQLServer数据库服务器内存配置的策略
    真正的取真实IP地址及利弊Asp.net
    ASP.NET一些常用正则表达式
    (CHMSoftware)工具集锦
    仿真方面的文章
    TPlan测试过程管理工具技术摘要
    Linux 2.6内核的精彩世界(多媒体)
    Ajax技术实践之完成Ajax自动完成功能
    硬件测试
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4572910.html
Copyright © 2020-2023  润新知