首页 > 其他分享 >CF1735E House Planning 题解

CF1735E House Planning 题解

时间:2024-02-08 20:01:16浏览次数:29  
标签:10 const int 题解 long leq Planning House define

题目大意

一条直线上有 \(n\) 个房子和两个人,房子的坐标 \(d_1,d_2,d_3\dots d_n\),以及两个人坐标为 \(p_1,p_2\)。

现在会告诉你两个集合 \(S_1=\{|p_1-d_i| ,1 \leq i \leq n\}\) 以及 \(S_2=\{|p_2-d_i|,1 \leq i \leq n\}\)。这个写法可能不是很规范,但为了美观就写成这样了。

现在需要你确定构造一组方案确定 \(p_1,p_2\) 以及 \(d_1,d_2,d_3\dots d_n\) 的值或者宣告无解。

数据范围为 \(n \leq 1000\)。


思路

思路还是比较直接的,考虑找到 \(S_1\) 中的一个元素 \(x\),在 \(S_2\) 中枚举哪一个元素与之匹配,不难发现这样 \(p_1,p_2\) 的坐标情况数量只有 \(2\) 种。

考虑对于这 \(2\) 种情况分开考虑,考虑剩下的元素怎么配对,假定 \((p_1,p_2)=(a,b)\)。

如果一个元素 \(x \in S_1\) 可以和 \(y \in S_2\) 配对,即算出来的 \(p_1,p_2\) 符合 \(a,b\),那么向他们之间连一条边。

然后跑网络流,看是否存在符合条件的解。

时间复杂度 \(O(n^2\sqrt n)\)。

代码写的很难看。

#include<bits/stdc++.h>

#define int long long

#define vc vector
#define db double
#define fi first
#define se second
#define ll long long
#define mk make_pair
#define pb push_back
#define RI register int
#define PI pair<int,int>
#define ull unsigned long long
#define err cerr << "   -_-   " << endl
#define debug cerr << " ------------------- " << endl

#define NO puts("NO")
#define YES puts("YES")

using namespace std;

namespace IO{
	inline int read(){
		RI X=0, W=0;register char ch=getchar();
		while(!isdigit(ch)) W|=ch=='-', ch=getchar();
		while(isdigit(ch)) X=(X<<1)+(X<<3)+(ch^48), ch=getchar();
		return W?-X:X;
	}
	inline void write(int x){
		if(x<0) x=-x, putchar('-');
		if(x>9) write(x/10);
		putchar(x%10+'0');
	}
	inline void sprint(int x){write(x), putchar(32);}
	inline void eprint(int x){write(x), putchar(10);}
}using namespace IO;

const int MAXN = 4e5+5;
const int mod1 = 998244353;
const int mod2 = 1e9+7;
const int inf = 1e12;

int head[5004], ne[MAXN<<1], to[MAXN<<1], weight[MAXN<<1], cnt=1;
int hd, tl, Q[MAXN], cur[MAXN], de[5004], s, t, len, c[MAXN], now, a[MAXN], b[MAXN], n, sol, h[MAXN];

inline void add(int x, int y, int w){
	++cnt;to[cnt]=y;ne[cnt]=head[x];head[x]=cnt;weight[cnt]=w;
	return ;
}

inline bool spfa(){
	memset(de,0,sizeof de);de[s]=1;
	Q[hd=tl=1]=s;int now;
	while(hd<=tl){
		now=Q[hd++];cur[now]=head[now];
		if(now==t) return 1;
		for(int i=head[now];i;i=ne[i]){
			if(!weight[i] || de[to[i]]) continue;
			de[to[i]]=de[now]+1;Q[++tl]=to[i];
		}
	}
	return 0;
}

inline int dinic(int now, int flow){
	if(now==t) return flow;
	int maxnflow=0, res;
	for(int i=cur[now];i && flow;i=ne[i]){
		cur[now]=i;
		if(weight[i] && de[to[i]]==de[now]+1){
			res=dinic(to[i],min(flow,weight[i]));
			weight[i]-=res;
			weight[i^1]+=res;
			flow-=res;
			maxnflow+=res;
		}
	}
	if(maxnflow==0) de[now]=0;
	return maxnflow;
}

int tmp;

inline int Get(int v){
	tmp=lower_bound(b+1,b+1+len,v)-b;
	if(b[tmp]==v) return tmp;
	return 2e9;
}

inline void Add(int node, int v){
	if(v>=1e9 || v<0) return ;
	add(node,v,1);
	add(v,node,0);
}

inline void output(int p1, int p2, int dis){
	h[1]=1e9;int r;
	for(int i=2;i<=n;++i){
		for(int j=head[i];j;j=ne[j]){
			if(to[j]!=s){
				if(weight[j]==0){
					r=to[j]-n;
					if(b[r]==a[i]+dis) h[i]=p1-a[i];
					else if(b[r]==a[i]-dis) h[i]=p1+a[i];
					else if(b[r]+a[i]==dis) h[i]=p1+a[i];
					break;
				}
			}
		}
	}
	int minn=3e9;minn=min(minn,p1), minn=min(minn,p2);
	for(int i=1;i<=n;++i) minn=min(minn,h[i]);
	p1-=minn, p2-=minn;
	for(int i=1;i<=n;++i) sprint(h[i]-minn);
	putchar(10);
	sprint(p1), eprint(p2);
}

inline void Judge(int p1, int p2, int dis, int i){
		if(p1>p2) return ;
		int maxnflow=0;
		memset(head,0,sizeof head);cnt=1;
		for(int j=2;j<=n;++j){
			if(a[j]<=dis) {
				Add(j,Get(dis+a[j])+n);
				Add(j,Get(dis-a[j])+n);
			}
			else{
				Add(j,Get(dis+a[j])+n);
				Add(j,Get(a[j]-dis)+n);
			}
			Add(s,j);
		}
		for(int j=1;j<=n;++j){
			if(j==i) continue;
			add(c[j]+n,j+2*n,1);
			add(j+2*n,c[j]+n,0);
			add(j+2*n,t,1);
			add(t,j+2*n,0);
		}
		maxnflow=0;
		while(spfa()) maxnflow+=dinic(s,inf);
		if(maxnflow==n-1){
			YES;
			sol=1;
			output(p1,p2,dis);
			return ;
		}
}

inline void solve(){
	n=read();s=0, t=3*n+1;
	for(int i=1;i<=n;++i) a[i]=read();
	for(int i=1;i<=n;++i) b[i]=read(), c[i]=b[i];
	sort(a+1,a+1+n);sort(b+1,b+1+n);
	bool flag=0;
	for(int i=1;i<=n;++i){
		if(a[i]==b[i]) continue;
		flag=1;break;
	}
	len=unique(b+1,b+1+n)-b-1;
	b[0]=b[len+1]=-1;b[len+2]=-1;
	for(int i=1;i<=n;++i)
		c[i]=lower_bound(b+1,b+1+len,c[i])-b;
	if(flag==0){
		YES;
		for(int i=1;i<=n;++i) sprint((long long)1e9-a[i]);
		putchar(10);
		sprint(1e9), eprint(1e9);
		return ;
	}
	int p1, p2, pos, dis;
	int maxnflow=0;sol=0;
	for(int i=1;i<=n;++i){
		pos=1e9;
		Judge(pos-a[1],pos+b[c[i]],a[1]+b[c[i]],i);
		if(sol) return ;
		Judge(pos-a[1],pos-b[c[i]],abs(a[1]-b[c[i]]),i);
		if(sol) return ;
		Judge(pos+a[1],pos+b[c[i]],abs(a[1]-b[c[i]]),i);
		if(sol) return ;
	}
	NO;
	return ;
}

signed main(){
	int t=read();
	while(t--) solve();
	return 0;
}

标签:10,const,int,题解,long,leq,Planning,House,define
From: https://www.cnblogs.com/OccasionalDreamer/p/18012077

相关文章

  • CF1847E Triangle Platinum? 题解
    感谢@swiftc管理反馈的信息,对于题目大意确定的东西进行了完善。交互题。题目大意有一个长度为\(n\)的序列\(a\)满足\(1\leqa_i\leq4\),现在你可以进行不超过\(5500\)次询问,每次询问询问三个数\(1\leqi<j<k\leqn\),你将会得到\(a_i,a_j,a_k\)构成的三角形......
  • [ABC327G] Many Good Tuple Problems 题解
    Description对于一对长度均为\(M\)且元素值在\(\left[1,N\right]\)之间的序列\((S,T)\),定义其为好的当且仅当:存在一个长度为\(N\)的\(01\)序列\(X\),使得其满足如下条件:对于任意\(i\in\left[1,M\right]\),有\(X_{S_i}\neqX_{T_i}\)。给定\(N,M\),求在......
  • CF1918G Permutation of Given 题解
    总体思路本题通过每次在已知序列中加入\(2\)个元素的方法,可以构造出满足条件的序列\(A\),这里提供一种新的构造方法。性质因为序列\(A\)中所有元素构成的可重集与序列\(B\)中所有元素构成的可重集完全相等,所以\(A\)中所有元素之和与\(B\)中所有元素之和相等。\[\s......
  • SP277 CTGAME - City Game 题解
    题目传送门前置知识单调栈解法令\(f_{i,j}(1\lei\len,1\lej\lem)\)表示从\((1,j)\)到\((i,j)\)中以\((i,j)\)结尾的均为F的子串长度,即\((i,j)\)上面可延伸的最大距离(子矩形的长)。用单调栈的第一维存储子矩形的长,第二维存储子矩形的宽。考虑依次枚举每一......
  • qoj8171 Cola 题解
    题目链接点击打开链接题目解法很牛的题!!!会不了一点令\(pref_i\)表示第\(i\)轮知道了前缀\([1,...,i]\)考虑怎样的\(pref\)序列是合法的(即采用最优策略):\(pref_0=0\)\(\forall_{i\in[0,n-1]}\;pref_i\lepref_{i+1}\)\(pref\)中\(x\)的出现次数\(\len-x-1\),因......
  • [AGC021E] Ball Eat Chameleons 题解
    Description有\(n\)只变色龙,一开始都是蓝色。现在你喂了\(k\)次球,每次指定一只变色龙吃下你指定颜色的球。一只变色龙从蓝色变成红色当且仅当它吃的红球比蓝球多;一只变色龙从红色变成蓝色当且仅当它吃的蓝球比红球多。求最后能使所有变色龙都变成红色的方案数。两个方案......
  • AT_abc270_g [ABC270G] Sequence in mod P 题解
    题目传送门前置知识大步小步算法解法递推式为\(x_{n}=(ax_{n-1}+b)\bmodp\),发现可以统一消去\(\bmodp\),只在最后参与计算。以下过程省去模运算。当\(x_{0}=t\)时,则\(n=0\)即为所求。当\(a=0,x_{0}\net\)时,递推式转化为\(x_{n}=b\bmodp\)。若\(b=t\),则......
  • UVA10225 Discrete Logging 题解
    题目传送门前置知识大步小步算法题意多组询问,每次询问依次给定\(p,a,b\),求\(a^{x}\equivb\pmod{p}\)的最小非负整数解,其中\(a,p\)互质。解法BSGS板子题,不做过多介绍。貌似本题比P3846[TJOI2007]可爱的质数/【模板】BSGS和BZOJ3239DiscreteLogging数据较强......
  • [AGC041F] Histogram Rooks 题解
    题目链接点击打开链接题目解法好牛(难)的题!!!所有都被覆盖不难想到容斥暴力的容斥是钦定集合\(S\)中的位置都没被覆盖,然后把不能填棋子的点都去掉,假设剩下的不受限制的点的个数为\(c\),则答案为\(\sum2^c(-1)^{|S|}\)这个暴力是很难直接优化的如果一列被有点被钦定了,那么......
  • 【洛谷 P2670】[NOIP2015 普及组] 扫雷游戏 题解(模拟)
    [NOIP2015普及组]扫雷游戏题目背景NOIP2015普及组T2题目描述扫雷游戏是一款十分经典的单机小游戏。在行列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的......