zoukankan      html  css  js  c++  java
  • [POI2007]EGZ-Driving Exam

    能到达所有路的充要条件是能到达左右两端的路

    用vector反向建边对每条路左右分别求个最长不上升子序列

    预处理出每条路向左向右分别需要多建多少路才能到达最左端和最右端

    然后跑个(Theta(n))的尺取法就可以了

    本题最长不上升子序列用vector+zkw线段树比二分更加好想?

    原来标程的solve函数尺取时出锅(但是居然AC了

    感谢我自己回来看题解发现看不懂

    现在这题解是真题解了

    #include"cstdio"
    #include"cstring"
    #include"iostream"
    #include"algorithm"
    #include"vector"
    using namespace std;
    
    const int MAXN=1<<17;
    
    int n,m,P,K,np;
    int f[2][MAXN];
    int tree[MAXN<<1];
    struct rpg{bool kd;int h,fl,fr;};
    vector<rpg> vec[MAXN];
    
    int read()
    {
    	int x=0;char ch=getchar();
    	while(ch<'0'||'9'<ch) ch=getchar();
    	while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
    	return x;
    }
    
    void calcl()
    {
    	for(int i=1;i<n;++i){
    		for(int j=0;j<vec[i].size();++j){
    			if(!vec[i][j].kd){
    				int l=MAXN+vec[i][j].h-1,r=MAXN+m+2,maxn=0;
    				while(l^r^1){
    					if(~l&1) maxn=max(maxn,tree[l^1]);
    					if(r&1) maxn=max(maxn,tree[r^1]);
    					l>>=1;r>>=1;
    				}vec[i][j].fl=maxn+1;
    			}
    		}for(int j=0;j<vec[i].size();++j){
    			if(!vec[i][j].kd){
    				for(int k=MAXN+vec[i][j].h;k;k>>=1){
    					tree[k]=max(tree[k],vec[i][j].fl);
    				}
    			}
    		}int l=MAXN,r=MAXN+m+2,maxn=0;
    		while(l^r^1){
    			if(~l&1) maxn=max(maxn,tree[l^1]);
    			if(r&1) maxn=max(maxn,tree[r&1]);
    			l>>=1,r>>=1;
    		}f[0][i+1]=maxn;
    	}return;
    }
    
    void calcr()
    {
    	for(int i=n;i>1;--i){
    		for(int j=0;j<vec[i].size();++j){
    			if(vec[i][j].kd){
    				int l=MAXN+vec[i][j].h-1,r=MAXN+m+2,maxn=0;
    				while(l^r^1){
    					if(~l&1) maxn=max(maxn,tree[l^1]);
    					if(r&1) maxn=max(maxn,tree[r^1]);
    					l>>=1;r>>=1;
    				}vec[i][j].fr=maxn+1;
    			}
    		}for(int j=0;j<vec[i].size();++j){
    			if(vec[i][j].kd){
    				for(int k=MAXN+vec[i][j].h;k;k>>=1){
    					tree[k]=max(tree[k],vec[i][j].fr);
    				}
    			}
    		}int l=MAXN,r=MAXN+m+2,maxn=0;
    		while(l^r^1){
    			if(~l&1) maxn=max(maxn,tree[l^1]);
    			if(r&1) maxn=max(maxn,tree[r&1]);
    			l>>=1,r>>=1;
    		}f[1][i-1]=maxn;
    	}return;
    }
    
    void init()
    {
    	n=read(),m=read(),P=read(),K=read();
    	for(int i=1;i<=P;++i){
    		int x=read(),y=read(),z=read();
    		if(z) vec[x].push_back((rpg){z^1,y+1});
    		else vec[x+1].push_back((rpg){z^1,y+1});
    	}calcl();memset(tree,0,sizeof(tree));calcr();
    	for(int i=1;i<=n;++i) f[0][i]=i-f[0][i]-1,f[1][i]=n-i-f[1][i];
    	return;
    }
    
    void solve()
    {
    	int ans=0,ct=0,cnt=0;
    	for(int i=1;i<=n;++i){
    		while(ct+1<=n&&f[1][i]+f[0][ct+1]<=K){
    			++ct;
    			if(!f[0][ct]&&!f[1][ct]) ++cnt;
    		}ans=max(ans,ct-i+1-cnt);
    		if(!f[0][i]&&!f[1][i]) --cnt;
    	}printf("%d
    ",ans);
    	return;
    }
    
    int main()
    {
    	init();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the EditerInput
    React 综合事件 SyntheticEvent
    浏览器进程?线程?
    如何选择Redux的store和React的state?
    主流浏览器内核介绍(前端开发值得了解的浏览器内核历史)
    前端路由实现与 react-router 源码分析
    Sass Less SCSS 的抉择
    单行居中显示文字,多行居左显示,最多两行超过用省略号结尾
    link和@import的区别
    css选择符属性继承优先级算法以及css3新增伪类新特性
  • 原文地址:https://www.cnblogs.com/AH2002/p/9620512.html
Copyright © 2011-2022 走看看