AGC043E

抄一下 https://www.luogu.com.cn/article/n32presk,写的非常好。

下面是要把问题转化为一个群论问题。

定义拓扑空间:全集 X 和它的一个子集族 T,使得 ,XT,且任意有限个元素的交在 T 中,任意元素(不要求有限或可数)的并在 T 中。

则称 (X,T) 是拓扑空间,T 内元素叫开集,不在的是闭集。

拓扑空间之间的函数 f:XY 是连续的,当且仅当 tTYf1(t)TX(数学分析中有形式一样的度量空间上的结论)

对于这道题,不用太在意这个定义,因为 R,R2 及其子空间的开集概念是熟知的。

下记 S1 为单位圆(就是首尾相接的 [0,1])。

对于拓扑空间 X,一条道路是 f:[0,1]X 的函数,一条闭曲线/回路是 f:S1X 的连续函数。

下面一段直接在道路 C,D:XY 的意义下说了。

闭曲线 CD 存在连续变化,当且仅当存在连续函数 F:X×[0,1]Y,使得 F(x,0)=C(x),F(x,1)=D(x),此时称 C,D 同伦。若还满足 F(0,x)=C(0)=D(0),F(1,x)=C(1)=D(1),这称为定端同伦,记为 [C]=[D]

定端同伦关系构成等价类,即 [C] 代表和 C 定端同伦的等价类。

定义道路 C(0)=x,C(1)=D(0)=y,D(1)=z 的乘积 CD:把 C 放在 [0,0.5]D 放在 [0.5,1],显然还是连续;扩展到等价类上,等价类的 是满足

[C][D]=[CD]

的运算。

对于定点 z 到自己的回路,这样的等价类和 构成群,其中单位元 ee(x)=z,而把回路翻转构成了逆元。这称为基本群 π(X,z)

一个拓扑空间 X 有强形变收缩核 AX,当 e(x)=x 和一个连续函数 r:XA 同伦,且同伦函数 H 满足 aA,t,H(a,t)=a(即 A 内部不变)。这个同伦把 [f]π(X,z) 同到了 [rf]π(A,z)

img

这表明 R2{x}{y} 可以收缩到两个 S1 在一个点上拼起来,记为 S1S1。显然,R2{x1,x2xn} 可以收缩到 S1S1S1,只需考虑 π(S1S1S1,z) 的结构。

不难看出(?) π(S1,z)=Z。而有:

塞弗特-范坎彭定理:π(AB,z)=π(A,z)π(AB,z)π(B,z),其中 是群自由积。

所以,π(S1S1S1,z)=ZZZ。对于本题的条件,记点集为 S={x1,x2,xn};这可以被看作是 xixi1 构成的串集合。

对于 TS,考虑嵌入 ι:R2SR2T 及其给出的同态 φST:π(R2S,z)π(R2T,z),这个同态具体是对于 iTxi 成为单位元 e,否则不变,而这些 iT 的自由群就是 R2T

一个闭曲线是同伦于单位元 e 的。那么问题变为:

对于一个自由群 F(x1,x2xn),找出 wF,使得 TS,[φST(w)=e]=AT

首先必须满足 A0=1,并且 RT,ARAT。下面构造展示,这也是充要条件。

记两元素的交换子是 [x,y]=xyx1y1。由于同态性,φ([x,y])=[φ(x),φ(y)]。这有的好性质是 [e,x]=[x,e]=e

wx=xwS=w{x1,x2xm}=[wx,wS{x1}]。如果限制为 AT=[ST],则可构造 wS 满足条件(可以归纳验证)。

进一步地,取出极小的 ARi=0。则可以验证,

iwRi

满足条件。总路径长度是 O(n3n) 的。

#include<bits/stdc++.h>
using namespace std;
#define pt array<int,2>
struct loop{vector<pt> a;};
loop inv(loop A){reverse(A.a.begin(),A.a.end());return A;}
loop operator *(loop A,loop B){
	loop C;
	for(auto u:A.a)C.a.push_back(u);
	for(int i=1;i<B.a.size();i++)C.a.push_back(B.a[i]);
	return C;
}
loop operator ^(loop A,loop B){
	return A*B*inv(A)*inv(B);
}
loop w(int x){
	loop A;A.a.push_back({0,0});
	for(int i=1;i<=x+1;i++)A.a.push_back({i,0});
	A.a.push_back({x+1,1});
	A.a.push_back({x,1});
	for(int i=x;i>=0;i--)A.a.push_back({i,0});
	return A;
}
loop w(vector<int> S){
	if(S.size()==1)return w(S[0]);
	int x=S.back();S.pop_back();
	return w(S)^w(x);
}
int A[(1<<6)+5],n;
string str;
vector<int> getS(int x){
	vector<int> S;
	for(int i=0;i<n;i++)if(x&(1<<i))S.push_back(i);
	return S;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>str;
	for(int i=0;i<(1<<n);i++)A[i]=str[i]-'0';
	int flg=A[0]==1;
	for(int i=0;i<(1<<n);i++)for(int j=0;j<(1<<n);j++)if((i&j)==j)flg&=(A[j]>=A[i]);
	if(!flg)return cout<<"Impossible"<<endl,0;
	cout<<"Possible"<<endl;
	loop ans;ans.a.push_back({0,0});
	for(int i=0;i<(1<<n);i++){
		if(A[i]==1)continue;
		bool cf=1;
		for(int j=0;j<i;j++)if((i&j)==j&&A[j]==0)cf=0;
		if(cf)ans=ans*w(getS(i));
	}
	cout<<ans.a.size()-1<<endl;
	for(auto [x,y]:ans.a)cout<<x<<" "<<y<<endl;
	return 0;
}

又快又好写,不知道为什么第一篇点赞更多。

posted @   British_Union  阅读(16)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示