Topcoder SRM 806 Div1 题解

Topcoder SRM 806 Div1 题解

比赛的时候做了300 和 500的,排名20左右。

300

大概就是将所有\((x,y)\)的东西放到\((k,x)\)

每一个点连到它的目标位置。

答案即为\(N^2-N+tot\)\(tot\) 是环个数。

可以发现这张图存在欧拉回路,直接dfs即可。

/*
{
######################
#       Author       #
#        Gary        #
#        2021        #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MAXN=40;
vector<int> g[MAXN];
vector<int> ans;
map<mp,int> era;
int n;
void dfs(int now){
	for(auto it:g[now]){
		if(era[II(now,it)]){
			continue;
		}
		era[II(now,it)]=1;
		dfs(it);
		ans.PB(it*n+now);
	}
}
class TransposeColors{
	public:
		vector <int> move(int N){
			n=N;
			if(N==1){
				return vector<int> (0);
			}
			rep(i,N)
				rep(j,N) if(i!=j) g[i].PB(j);
			dfs(0);
			ans.PB(N*N);
			return ans;
		}
}solver;

500

这题比较套路,处理出\(KMP\)直接dp。

dp的first为最大值,dp的second为方案数。

/*
{
######################
#       Author       #
#        Gary        #
#        2021        #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
int fail[101],to[101][26];
mp dp[1004][101];
const int MOD=1e9+7;
mp merge(mp A,mp B){
	if(A.FIR!=B.FIR) return max(A,B);
	return II(A.FIR,(A.SEC+B.SEC)%MOD);
}
class MostSubstrings{
	public:
		int count(string s, int l){
			int len=s.length();
			fail[0]=0;
			fail[1]=0;
			rb(i,2,len){
				fail[i]=fail[i-1];
				while(s[i-1]!=s[fail[i]]){
					if(fail[i]==0) break;
					fail[i]=fail[fail[i]];
				}
				if(s[i-1]==s[fail[i]]){
					fail[i]++;
				}
			}
			rb(i,0,len-1){
				rep(c,26){
					int now=i;
					while(s[now]-'a'!=c){
						if(now==0) break;
						now=fail[now];
					}
					if(s[now]-'a'!=c){
						to[i][c]=0;
					}
					else{
						to[i][c]=now+1;
					}
				}
			}
			rb(i,0,l)
				rb(j,0,len) dp[i][j]=II(0,0);
			dp[0][0]=II(0,1);
			rb(i,0,l-1){
				rb(j,0,len-1){
					if(dp[i][j].SEC||dp[i][j].FIR);
					else continue;
					rep(c,26){
						int nex=to[j][c];
						if(nex==len){
							dp[i+1][fail[len]]=merge(dp[i+1][fail[len]],II(dp[i][j].FIR+1,dp[i][j].SEC));
						}
						else{
							dp[i+1][nex]=merge(dp[i+1][nex],dp[i][j]);
						}
					}
				}
			}
			mp ans=II(0,0);
			rb(j,0,len-1) ans=merge(ans,dp[l][j]);
			return ans.SEC;
		}
}solver;
//int main(){
//	cout<<solver.count("decode",
//11)<<endl;
//	return 0;
//}

1000

结论比较神奇:

alice输当且仅当\(a_0=a_1=a_2\and a_4=a_5=a_6\and a_0\text{xor}a_3\text{xor}a_4=0\)

知道这个直接暴力即可。

证明:

首先若不满足条件则一定存在操作到达满足上面条件的操作。

若满足一定达到不满足的局面。

(感觉没证明。。。)

/*
{
######################
#       Author       #
#        Gary        #
#        2021        #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
int fail[101],to[101][26];
mp dp[1004][101];
const int MOD=1e9+7;
mp merge(mp A,mp B){
	if(A.FIR!=B.FIR) return max(A,B);
	return II(A.FIR,(A.SEC+B.SEC)%MOD);
}
class MostSubstrings{
	public:
		int count(string s, int l){
			int len=s.length();
			fail[0]=0;
			fail[1]=0;
			rb(i,2,len){
				fail[i]=fail[i-1];
				while(s[i-1]!=s[fail[i]]){
					if(fail[i]==0) break;
					fail[i]=fail[fail[i]];
				}
				if(s[i-1]==s[fail[i]]){
					fail[i]++;
				}
			}
			rb(i,0,len-1){
				rep(c,26){
					int now=i;
					while(s[now]-'a'!=c){
						if(now==0) break;
						now=fail[now];
					}
					if(s[now]-'a'!=c){
						to[i][c]=0;
					}
					else{
						to[i][c]=now+1;
					}
				}
			}
			rb(i,0,l)
				rb(j,0,len) dp[i][j]=II(0,0);
			dp[0][0]=II(0,1);
			rb(i,0,l-1){
				rb(j,0,len-1){
					if(dp[i][j].SEC||dp[i][j].FIR);
					else continue;
					rep(c,26){
						int nex=to[j][c];
						if(nex==len){
							dp[i+1][fail[len]]=merge(dp[i+1][fail[len]],II(dp[i][j].FIR+1,dp[i][j].SEC));
						}
						else{
							dp[i+1][nex]=merge(dp[i+1][nex],dp[i][j]);
						}
					}
				}
			}
			mp ans=II(0,0);
			rb(j,0,len-1) ans=merge(ans,dp[l][j]);
			return ans.SEC;
		}
}solver;
//int main(){
//	cout<<solver.count("decode",
//11)<<endl;
//	return 0;
//}
posted @ 2021-05-27 15:44  WWW~~~  阅读(53)  评论(0编辑  收藏  举报