• [CEOI2018]Global warming


    [CEOI2018]Global warming

    题目大意:

    给定(n(nle2 imes10^5)),你可以将任意(a_{lsim r}(1le lle rle n))每一个元素加上一个(d(|d|le x)),求(a)的LIS长度。

    思路:

    不难发现区间加一个数是为了使得LIS中间一段比左边一段大,而右边一段本来就比中间的大,那么我们给右边一段同时加上也不会影响答案。因此我们可以给一个后缀加上(x)求LIS即可。

    用两个树状数组分别维护,当前是否是已被增加过的后缀,前缀LIS的最大值。

    时间复杂度(mathcal O(nlog n))

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=2e5+1;
    int a[N],tmp[N*2];
    class SegmentTree {
    	private:
    		int val[N*2];
    		int lowbit(const int &x) const {
    			return x&-x;
    		}
    	public:
    		void modify(int p,const int &x) {
    			for(;p<=tmp[0];p+=lowbit(p)) {
    				val[p]=std::max(val[p],x);
    			}
    		}
    		int query(int p) const {
    			int ret=0;
    			for(;p;p-=lowbit(p)) {
    				ret=std::max(ret,val[p]);
    			}
    			return ret;
    		}
    };
    SegmentTree t[2];
    int main() {
    	const int n=getint(),x=getint();
    	for(register int i=1;i<=n;i++) {
    		tmp[i]=a[i]=getint();
    		tmp[n+i]=a[i]+x;
    	}
    	std::sort(&tmp[1],&tmp[n*2]+1);
    	tmp[0]=std::unique(&tmp[1],&tmp[n*2]+1)-&tmp[1];
    	for(register int i=1;i<=n;i++) {
    		const int pos1=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,a[i]+x)-tmp;
    		t[1].modify(pos1,t[0].query(pos1-1)+1);
    		t[1].modify(pos1,t[1].query(pos1-1)+1);
    		const int pos0=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,a[i])-tmp;
    		t[0].modify(pos0,t[0].query(pos0-1)+1);
    	}
    	printf("%d
    ",t[1].query(tmp[0]));
    	return 0;
    }
    
  • 相关阅读:
    CSS实现小三角小技巧
    Javascript原型继承 __proto__
    99乘法表
    函数式编程之纯函数
    函数式编程 本质(笔记)转载
    函数式编程之柯里化(curry)
    Javascript-常用字符串数组操作
    第十章
    第九章
    第八章读后感
  • 原文地址:https://www.cnblogs.com/skylee03/p/9633642.html
Copyright © 2020-2023  润新知