zoukankan      html  css  js  c++  java
  • CF 1606 D题题解

    CF 1606 D题题解

    题意:给定(n*m)的矩阵(A=a_{i,j}),需要给每一行染上红色或者蓝色,使得存在一个划分(k) ((1 leq k leq m-1)) 将m列分为左右两块,使得:

    1.左边矩阵中颜色为红色的(a)的最小值大于颜色为蓝色的(a)的最大值;

    2.右边矩阵中颜色为蓝色的(a)的最小值大于颜色为红色的(a)的最大值。

    若存在合法方案,输出染色情况和(k);若不存在,输出"NO"。若存在多解,可输出任意一个。

    多组数据,(n imes m leq 5 imes 10^5)

    题解:首先确定时间复杂度一定是(O(nmlog^kn))。枚举(k),然后用(O(nlogn))的复杂度判断合法性。

    将矩阵分为前(k)列和后(m-k)列,分开考虑如何选取一些行涂成红色。容易看出左边一定是按行最小值从大到小排序,依次选择;右边则是按行最大值升序排序,依次选择。当两边选择的行的集合完全重合时,这样的划分就有可能成为一种合法方案(即一个必要条件)。将所有这样的集合(S)存到一个map里。

    再重复这个过程去选涂成蓝色的行。将所有集合(T)存到另一个map里。

    如果存在一个(S)和一个(T)使得(S)(T)的并集为全集-----那么离合法方案仅差一步:

    至此我们只得到了一个完整的划分,但并不能保证这样的划分(S,T)满足条件。这时候就体现出分别做两次的优势了:我们在将(S)(T)加入map时,同时可以存下左边和右边的某颜色的最值,这样就能方便比较了。

    (O(n))的复杂度内求出(k)确定时每一行左右两边的最值是oier应具备的基本素质,这里不再细说。

    时间复杂度:(O(nmlogn))

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define re register int
    #define F(x,y,z) for(re x=y;x<=z;x++)
    #define FOR(x,y,z) for(re x=y;x>=z;x--)
    typedef long long ll;
    typedef __int128 i128;
    #define I inline void
    #define IN inline int
    #define C(x,y) memset(x,y,sizeof(x))
    #define STS system("pause")
    #define Debug(x,y) F(i,1,y)cout<<x[i]<<" ";cout<<endl;
    template<class D>I read(D &res){
    	res=0;re g=1;register char ch=getchar();
    	while(!isdigit(ch)){
    		if(ch=='-')g=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch)){
    		res=(res<<3)+(res<<1)+(ch^48);
    		ch=getchar();
    	}
    	res*=g;
    }
    typedef pair<int,int>pii;
    const int Mod=998244353,INF=1e7;
    int n,m,T,X,Y,wx,wy,sn,vis[505000],t[505000],mx[505000],mn[505000],xm[505000],nm[505000];
    map<int,pii>mp;map<int,int>to; 
    priority_queue<pii>px;
    priority_queue<pii,vector<pii>,greater<pii> >py;
    vector<int>v[505000],up[505000],dn[505000];
    int main(){
    	t[0]=1;
    	F(i,1,500001)t[i]=(t[i-1]<<1)%Mod,to[t[i]]=i;
    	read(T);
    	while(T--){
    		read(n);read(m);sn=0;
    		F(i,1,n){
    			vis[i]=0;
    			v[i].resize(m+1);up[i].resize(m+1);dn[i].resize(m+1);
    			F(j,1,m)read(v[i][j]);
    			re maxi=v[i][m],mini=v[i][m];up[i][m]=dn[i][m]=m;
    			FOR(j,m-1,1){
    				if(v[i][j]>maxi)up[i][j]=j,maxi=v[i][j];
    				else up[i][j]=up[i][j+1];
    				if(v[i][j]<mini)dn[i][j]=j,mini=v[i][j];
    				else dn[i][j]=dn[i][j+1];
    			} 
    			xm[i]=maxi;nm[i]=mini;
    		}
    		F(i,1,n)mx[i]=-INF,mn[i]=INF;
    		F(j,1,m-1){
    			mp.clear();X=Y=0;
    			while(!px.empty())px.pop();
    			while(!py.empty())py.pop();
    			F(i,1,n){
    				if(v[i][j]>mx[i])mx[i]=v[i][j];
    				if(v[i][j]<mn[i])mn[i]=v[i][j];
    				if(up[i][j]==j)xm[i]=v[i][up[i][j+1]];
    				if(dn[i][j]==j)nm[i]=v[i][dn[i][j+1]];
    				//cout<<mx[i]<<" "<<mn[i]<<" "<<xm[i]<<" "<<nm[i]<<endl;
    				px.push(make_pair(mn[i],t[i]));
    				py.push(make_pair(xm[i],t[i]));
    			}
    			F(i,1,n-1){
    				wx=px.top().first;(X+=px.top().second)%=Mod;px.pop();
    				wy=py.top().first;(Y+=py.top().second)%=Mod;py.pop();
    				//cout<<X<<" "<<Y<<endl;
    				if(wx>px.top().first&&wy<py.top().first&&X==Y)mp[X]=make_pair(wx,wy);
    			}
    			//cout<<"Check"<<endl;
    			X=Y=(t[n+1]+Mod-2)%Mod;
    			while(!px.empty())px.pop();while(!py.empty())py.pop();
    			F(i,1,n)px.push(make_pair(nm[i],t[i])),py.push(make_pair(mx[i],t[i]));
    			F(i,1,n-1){
    				wx=py.top().first;(X+=Mod-py.top().second)%=Mod;py.pop();
    				wy=px.top().first;(Y+=Mod-px.top().second)%=Mod;px.pop();
    				//cout<<X<<" "<<Y<<endl;
    				if(wx<py.top().first&&wy>px.top().first&&X==Y&&mp.find(X)!=mp.end()&&wx<mp[X].first&&wy>mp[X].second){
    					sn=1;cout<<"YES"<<endl;
    					while(!py.empty())vis[to[py.top().second]]=1,py.pop();
    					F(k,1,n){
    						if(vis[k])putchar('R');
    						else putchar('B');
    					}
    					cout<<" "<<j<<endl;
    					break;
    				}
    			}
    			//cout<<"End"<<endl;
    			if(sn)break;
    		}
    		/*if(!sn){
    			re j=m;
    			mp.clear();X=0;Y=(t[n+1]+Mod-2)%Mod;
    			F(i,1,n){
    				if(v[i][j]>mx[i])mx[i]=v[i][j];
    				if(v[i][j]<mn[i])mn[i]=v[i][j];
    				px.push(make_pair(mn[i],t[i]));
    				py.push(make_pair(mx[i],t[i]));
    			}
    			F(i,1,n-1){
    				wx=px.top().first;(X+=px.top().second)%=Mod;px.pop();
    				mp[X]++;
    			}
    			
    			F(i,1,n-1){
    				wy=py.top().first;(Y+=Mod-py.top().second)%=Mod;py.pop();
    				if(mp[Y]){
    					sn=1;cout<<"YES"<<endl;
    					while(!py.empty())vis[to[py.top().second]]=1,py.pop();
    					F(k,1,n){
    						if(vis[k])putchar('R');
    						else putchar('B');
    					}
    					cout<<" "<<j<<endl;
    					break;
    				}
    			}
    		}*/
    		if(!sn)cout<<"NO"<<endl;
    	}
    	
    	return 0;
    }
    
    
  • 相关阅读:
    EntityFramework 迁移遇到的问题
    Eclipse下使用PySpark报Could not find valid SPARK_HOME while searching
    Eclipse下使用PySpark报Could not find valid SPARK_HOME while searching
    Eclipse下使用PySpark报Could not find valid SPARK_HOME while searching
    Eclipse下使用PySpark报Could not find valid SPARK_HOME while searching
    通过fiddler抓取IDEA的请求
    Visual Studio中你所不知道的智能感知
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    区块链的诞生及演化
  • 原文地址:https://www.cnblogs.com/Purple-wzy/p/15484736.html
Copyright © 2011-2022 走看看