zoukankan      html  css  js  c++  java
  • CF1208E Let Them Slide

    codeforces

    由于每个数组可以滑动。

    我们对于一个位置,要考虑它是否可以为空,能放的最大值是多少。

    每行的每个位置都直接这样做显然会TLE。

    我们发现每行可以分为三个部分(有些时候不可以,随便讨论一下啦)

    第一个部分是只能放前几个。

    第二个部分是所有的都可以放。

    第三个部分是只能放后几个。

    然后我们发现第二个部分都是一样的,直接线段树区间处理就行了

    第一个部分和第三个部分只能暴力,但是发现这两个部分最多为(2*l_i)

    所以总时间复杂度为(O(sum_{i=1}^{n}l_ilog m))

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    using namespace std;
    #define rg register
    void read(int &x){
        char ch;bool ok;
        for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
        for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
    }
    const int maxn=1e6+10;
    int n,m,mx[maxn*4];
    void build(int x,int l,int r){
        mx[x]=-2e9;if(l==r)return ;
        int mid=(l+r)>>1;
        build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    }
    void update(int x){mx[x]=max(mx[x<<1],mx[x<<1|1]);}
    void change(int x,int l,int r,int a,int c){
        if(l==r)return mx[x]=max(mx[x],c),void();
        int mid=(l+r)>>1;
        if(a<=mid)change(x<<1,l,mid,a,c);
        else change(x<<1|1,mid+1,r,a,c);
        update(x);
    }
    int get(int x,int l,int r,int a,int b){
        if(a<=l&&b>=r)return mx[x];
        int mid=(l+r)>>1,ans=-2e9;
        if(a<=mid)ans=max(ans,get(x<<1,l,mid,a,b));
        if(b>mid)ans=max(ans,get(x<<1|1,mid+1,r,a,b));
        return ans;
    }
    struct segment_tree{
        long long ans[maxn*4],la[maxn*4];
        void update(int x){ans[x]=max(ans[x<<1],ans[x<<1|1]);}
        void pushdown(int x){
    	ans[x<<1]+=la[x],ans[x<<1|1]+=la[x];
    	la[x<<1]+=la[x],la[x<<1|1]+=la[x];
    	la[x]=0;
        }
        void change(int x,int l,int r,int a,int b,int c){
    	if(a<=l&&b>=r)return ans[x]+=c,la[x]+=c,void();
    	int mid=(l+r)>>1;if(la[x])pushdown(x);
    	if(a<=mid)change(x<<1,l,mid,a,b,c);
    	if(b>mid)change(x<<1|1,mid+1,r,a,b,c);
    	update(x);
        }
        long long get(int x,int l,int r,int a){
    	if(l==r)return ans[x];
    	int mid=(l+r)>>1;if(la[x])pushdown(x);
    	if(a<=mid)return get(x<<1,l,mid,a);
    	else return get(x<<1|1,mid+1,r,a);
        }
    }T;
    signed main(){
        read(n),read(m);
        for(rg int i=1,w;i<=n;i++){
    	read(w);build(1,1,w);
    	for(rg int j=1,x;j<=w;j++)read(x),change(1,1,w,j,x);
    	int now=get(1,1,w,1,w),l=w+1,r=m-w;
    	if(w+1<=m-w)now=max(now,0),T.change(1,1,m,w+1,m-w,now);
    	else if(w>=m-w+1){
    	    l=m-w+1,r=w;
    	    for(rg int j=l;j<=r;j++){
    		now=get(1,1,w,j-m+w,j);
    		T.change(1,1,m,j,j,now);
    	    }
    	}
    	for(rg int j=1;j<l;j++){
    	    now=get(1,1,w,1,j);now=max(now,0);
    	    T.change(1,1,m,j,j,now);
    	}
    	for(rg int j=r+1;j<=m;j++){
    	    now=get(1,1,w,w-m+j,w);now=max(now,0);
    	    T.change(1,1,m,j,j,now);
    	}
        }
        for(rg int i=1;i<=m;i++)printf("%lld ",T.get(1,1,m,i));
    }
    
  • 相关阅读:
    Java语法基础
    配置环境变量
    常用Dos命令
    Python 之 进程与进程池的创建和使用
    python之进程间通信
    低级别网络接口-socket的应用和粘包现象
    网络编程之模块的使用
    Python异常类型
    练习题
    python 的re模块与正则表达式
  • 原文地址:https://www.cnblogs.com/lcxer/p/11505978.html
Copyright © 2011-2022 走看看