首页 > 其他分享 >The 2023 CCPC Guilin J. The Phantom Menace

The 2023 CCPC Guilin J. The Phantom Menace

时间:2023-11-16 16:48:40浏览次数:35  
标签:Phantom typedef Menace const int Guilin Hasher include define

好劲的字符串题,然而实际上和字符串没啥关系

比赛的时候全队应该就只有我没读过题面,感觉如果让我看到这个重排+循环同构第一反应肯定是枚举偏移量+Hash比较前后缀,因为我字符串算法高级的不会只会一个Hash,说不定能搞出点想法

但今天补的时候发现写起来细节还是挺多的,尤其是有向图的欧拉回路和无向图版本不太一样,去网上重新找了个写法才过

回到题目,循环同构的解决思路一般就是枚举一个偏移量\(x\),之后我们发现问题转化为:

  • 第一个集合中的串长度为\(x\)的前缀和第二个串中长度为\(x\)的后缀匹配
  • 第二个集合中长度为\(n-x\)的前缀和第一个集合中长度为\(n-x\)的后缀匹配

一个很直观的想法就是把每个字符串看成点,然后把分割后有相同部分的关系看成边,但这样有个问题就是可能会出现边数爆炸的情况

因此不妨换个角度思考,把对应长度的前后缀看成点,然后将字符串看作边,这样图中的边数就是\(O(n)\)级别的,同时相同部分由于会映射到同一个点上,也就变相实现了匹配的功能

再手玩一下就会发现此时题目转化为在得到的图上找一个欧拉回路,然后直接上板子即可

总复杂度\(O(n\times m)\)

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef __int128 i128;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=2e6+5;
int t,n,m,deg[N],idx; char s[N]; vector <pi> v[N];
const int mod1=998244353,mod2=1e9+7;
struct Hasher
{
	int x,y;
	inline Hasher(CI X=0,CI Y=0)
	{
		x=X; y=Y;
	}
	inline LL get_val(void)
	{
		return ((1LL*x)<<31LL)|(1LL*y);
	}
	friend inline bool operator == (const Hasher& A,const Hasher& B)
	{
		return A.x==B.x&&A.y==B.y;
	}
	friend inline Hasher operator + (const Hasher& A,const Hasher& B)
	{
		return Hasher((A.x+B.x)%mod1,(A.y+B.y)%mod2);
	}
	friend inline Hasher operator - (const Hasher& A,const Hasher& B)
	{
		return Hasher((A.x-B.x+mod1)%mod1,(A.y-B.y+mod2)%mod2);
	}
	friend inline Hasher operator * (const Hasher& A,const Hasher& B)
	{
		return Hasher(1LL*A.x*B.x%mod1,1LL*A.y*B.y%mod2);
	}
}pw[N]; vector <Hasher> h[N]; vector <int> path; int used[N];
const Hasher seed=Hasher(31,131);
inline void init(CI n)
{
	pw[0]=Hasher(1,1); for (RI i=1;i<=n;++i) pw[i]=pw[i-1]*seed;
}
inline Hasher get_hsh(CI id,CI l,CI r)
{
	return h[id][r]-h[id][l-1]*pw[r-l+1];
}
inline void DFS(CI now)
{
	while (!v[now].empty())
	{
		int to=v[now].back().fi,id=v[now].back().se; v[now].pop_back();
		if (used[id]) continue; DFS(to); used[id]=1; path.push_back(id);
	}
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t),init(1e6);t;--t)
	{
		RI i,j; for (scanf("%d%d",&n,&m),i=1;i<=2*n;++i)
		{
			h[i].resize(m+1); h[i][0]=Hasher(); scanf("%s",s+1);
			for (j=1;j<=m;++j) h[i][j]=h[i][j-1]*seed+Hasher(s[j],s[j]);
		}
		bool sign=0; for (i=0;i<m;++i) //shift
		{
			for (j=1;j<=idx;++j) deg[j]=0,v[j].clear(); idx=0;
			map <LL,int> rst[2]; int st;
			auto get_id=[&](CI tp,const LL& val)
			{
				if (!rst[tp].count(val)) rst[tp][val]=++idx; return rst[tp][val];
			};
			for (j=1;j<=n;++j)
			{
				int x=get_id(0,get_hsh(j,1,i).get_val()),y=get_id(1,get_hsh(j,i+1,m).get_val());
				st=x; v[x].push_back(pi(y,j)); ++deg[x]; --deg[y];
			}
			for (j=n+1;j<=2*n;++j)
			{
				int x=get_id(1,get_hsh(j,1,m-i).get_val()),y=get_id(0,get_hsh(j,m-i+1,m).get_val());
				v[x].push_back(pi(y,j)); ++deg[x]; --deg[y];
			}
			bool flag=1; for (j=1;j<=idx;++j) if (deg[j]) { flag=0; break; }
			if (!flag) continue; path.clear(); for (j=1;j<=2*n;++j) used[j]=0;
			/*for (j=1;j<=idx;++j)
			{
				printf("%d -> ",j);
				for (auto [x,y]:v[j]) printf("(%d,%d) ",x,y); putchar('\n');
			}*/
			DFS(st); for (j=1;j<=2*n;++j) if (!used[j]) { flag=0; break; }
			if (!flag) continue; reverse(path.begin(),path.end());
			vector <int> pa,pb; for (auto x:path)
			if (x<=n) pa.push_back(x); else pb.push_back(x-n);
			sign=1; for (auto x:pa) printf("%d ",x); putchar('\n');
			for (auto x:pb) printf("%d ",x); putchar('\n'); break;
		}
		if (!sign) puts("-1");
	}
	return 0;
}

标签:Phantom,typedef,Menace,const,int,Guilin,Hasher,include,define
From: https://www.cnblogs.com/cjjsb/p/17836641.html

相关文章

  • The 2023 CCPC Guilin 游记
    Preface纯在偷懒,比赛结束过了这么多天才把这篇游记摸出来这场CCPC桂林算是我们全队第一次线下打区域赛,虽然赛前VP往年CCPC时偶尔也能打进金牌区(一般都是徐神切出字符串或是祁神切掉计算几何时)但鉴于没啥经验而且这场桂林强队如云,因此心理预期能守银就算成功最后的结果也算是中......
  • 常见问题解决 --- 安卓12关闭phantom processes killer杀后台功能
    1.adb连接成功后,执行adbdevices2.执行adbshell3.执行device_configset_sync_disabled_for_testspersistentdevice_configputactivity_managermax_phantom_processes2147483647settingsputglobalsettings_enable_monitor_phantom_procsfalse......
  • The 2021 CCPC Guilin Onsite (XXII Open Cup, Grand Prix of EDG)
    Preface昨天下午16:30~21:30刚打完CCPC2021的广州,今天早上九点又开始打这场桂林,压力拉满了属于是这场比起昨天那场良心太多了,开场还挺顺(虽然因为写Dijkstra偷懒TLE了四发),但开题啥的都是见一个会一个中期虽然有点卡但因为祁神会了几何所以没有空机,然后再点完外卖后我突然顿悟把BK......
  • 2022 China Collegiate Programming Contest (CCPC) Guilin Site(持续更新)
    Preface由于还有两周就要滚去打区域赛了,这周开始周末每天都训一场吧这场总体来说打的还可以,虽然E题这个Easy从卡局卡到3h,但由于其它的题都是一遍过所以罚时还尚可跻进Au区后面一个小时看徐神和祁神苦战K大分类讨论,虽然场下感觉摸了一个B的做法出来,但感觉实现还是太麻烦了就没写......
  • 2021 China Collegiate Programming Contest (CCPC) Guilin Site
    A.AHeroNamedMagnus#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongusingpii=pair<int,int>;usingvi=vector<int>;voidsolve(){intx;cin>>x;cout<<2ll*x-1<<"......
  • String Rearrangement in Phantom
    先考虑一个\(O(nq)\)的暴力,令\(s_{1}=S[l_{1},r_{1}],s_{2}=S[l_{2},r_{2}]\),令\(t=\operatorname{rev}(s_{2})\),则我们仅需求\(s_{1}=A+B+C,t=\operatorname{rev}(A)+B+\operatorname{rev}(C)\)的数量,对于每一个前缀和后缀求出其翻转是否与其相等即可,这个可以通过\(\text{......
  • [爬虫]2.2.2 使用PhantomJS处理JavaScript
    PhantomJS是一个无头(headless)浏览器,它可以解析和执行JavaScript,非常适合用于爬取动态网页。"无头"意味着它可以在没有用户界面的情况下运行,这对于服务器环境和自动化任务非常有用。安装PhantomJS首先,你需要下载并安装PhantomJS。你可以从官方网站下载↗适合你的操作系统的版本......
  • 记phantomjs中文乱码
    参考博客:https://blog.csdn.net/fgangen/article/details/103235401 如下图所示,左上角中文乱码,环境是centos7,在https://www.cnblogs.com/weiyanei/p/17167686.html中介绍了后台生成echarts图片,但是部署在linux上发现乱码,试了好多种方法,还是那个参考博客好用。 直接将C:\Wi......
  • 基于PhantomJS的网站截图服务API设计与开发
    为公司某业务实现“服务端对网站截图”功能,搜罗了很多技术最终采用了PhantomJS无头浏览器技术。什么是PhantomJS?PhantomJS是一个基于webkit的javaScriptAPI。它使用QtWebKit作为它核心浏览器的功能,使用webkit来编译解释执行javaScript代码。任何你可以基于在webkit浏览器做的事情,......
  • 2022CCPC Guilin Site E. Draw a triangle
    Drawatriangle题意:给定两点,求第三个整数点满足三点构成的非退化三角形面积最小分析:一开始看成了图论题,以为一直在卡精度(doge设\(A(x_1,y_1),B(x_2,y_2),C(x,y)\),则三角形面积由向量叉积求:\(2S=\vec{AB}×\vec{AC}\)\(\vec{AB}\)表示为\((x_2-x_1,y_2-y_......