zoukankan      html  css  js  c++  java
  • 数组分块入门 3

    传送门

    第一次用读入挂,感觉还行。

    这题和数组分块2的题目差不多,只不过求的是最大前驱。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100000+10;
    #define ll long long
    int  a[maxn],belong[maxn],l[1005],r[1005],lazy[1005],block,num,n;
    vector<int>v[1005];
    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;
    }
    inline void build()
    {
        memset(lazy,0,sizeof(lazy));
        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;
            v[belong[i]].push_back(a[i]);
        }
        for(int i=1;i<=num;i++)
            sort(v[i].begin(),v[i].end());
    }
    inline void reset(int x)
    {
        v[x].clear();
        for(int i=l[x];i<=r[x];i++)
            v[x].push_back(a[i]);
        sort(v[x].begin(),v[x].end());
    }
    inline void update(int left,int right,int c)
    {
        if(belong[left]==belong[right])
        {
            for(int i=left;i<=right;i++)
                a[i]+=c;
            reset(belong[left]);
        }
        else
        {
            for(int i=left;i<=r[belong[left]];i++)
                a[i]+=c;
            reset(belong[left]);
            for(int i=l[belong[right]];i<=right;i++)
                a[i]+=c;
            reset(belong[right]);
            for(int i=belong[left]+1;i<=belong[right]-1;i++)
                lazy[i]+=c;
        }
    }
    inline void query(int left,int right,int c)
    {
        ll ans=-1e15;
        if(belong[left]==belong[right])
        {
            for(int i=left;i<=right;i++)
                if(a[i]+lazy[belong[i]]<c)
                    ans=max(ans,(ll)(a[i]+lazy[belong[i]]));
        }
        else
        {
            for(int i=left;i<=r[belong[left]];i++)
                if(a[i]+lazy[belong[i]]<c)
                    ans=max(ans,(ll)(a[i]+lazy[belong[i]]));
            for(int i=l[belong[right]];i<=right;i++)
                if(a[i]+lazy[belong[i]]<c)
                    ans=max(ans,(ll)(a[i]+lazy[belong[i]]));
            for(int i=belong[left]+1;i<=belong[right]-1;i++)
            {
                int pos=lower_bound(v[i].begin(),v[i].end(),c-lazy[i])-v[i].begin();
                if(pos==0) continue;
                ans=max(ans,(ll)(v[i][pos-1]+lazy[i]));
            }
        }
        if(ans==(-1e15))
            cout<<-1<<endl;
        else
            cout<<ans<<endl;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        build();
        for(int i=1;i<=n;i++)
        {
            int opt,left,right,c;
            opt=read(),left=read(),right=read(),c=read();
            if(!opt)
                update(left,right,c);
            else
                query(left,right,c);
        }
        return 0;
    }
  • 相关阅读:
    c# linq.Where+Func<object,bool>筛选数据
    【转】深入线程安全容器的实现方法
    c# 泛型+反射
    c# List<接口>小技巧
    winfrom的右击菜单项事件中如何获取关联控件的引用
    ASP.NET 1.0
    让包含GridView的div或panel的滚动条自己拉到底部怎么做?
    微软的IE中调试JavaScript的工具下载链接
    ASP.NET调试启动默认浏览器如何设置
    C# WinForm的PictureBox控件图片的拉伸或收缩方式跟随着控件的大小
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754899.html
Copyright © 2011-2022 走看看