20201126模拟

T1

将每一个单词中的各个字母的数量统计出来,然后可以得到一个表示字母数量的数列,将它哈希一下即可

#include <cstdio>
#include <cstring>
#include <algorithm>

#define ll long long

using namespace std;

int read()
{
	int a = 0,x = 1;char ch = getchar();
	while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
	while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
	return a*x;
}

const int hash1 = 131,hash2 = 133,P1 = 1000429,P2 = 20190631;
const int N=2e6+7;
int n;
int t[26];
ll sum = 0;
char s[107];
int val[N];
int head[N],go[N],nxt[N],cnt;
void add(int u,int v)
{
	go[++cnt] = v;
	nxt[cnt] = head[u];
	head[u] = cnt;
	val[cnt] = 1;
}

int main()
{
	freopen("anagram.in","r",stdin);
	freopen("anagram.out","w",stdout);
	n = read();
	for(int i = 1;i <= n;i ++) {
		scanf("%s",s);
		for(int j = strlen(s)-1;~j;j --) {
			t[s[j]-'a'] ++;
		}
		int tmp1=0,tmp2=0;
		for(int j = 0;j < 26;j ++) {
			tmp1 = (1ll*tmp1*hash1 + t[j])%P1;
			tmp2 = (1ll*tmp2*hash2 + t[j])%P2;
			t[j] = 0;
		}
		bool flag = 0;
		for(int e = head[tmp1];e;e = nxt[e]) {
			int v = go[e];
			if(v == tmp2) {
				flag = 1;
				printf("%lld\n",sum += (val[e]++));
				break;
			}
		}
		if(!flag) {add(tmp1,tmp2);printf("%lld\n",sum);}
	}
	return 0;
}

T2

使用 BFS 预处理各个点之间的间距,然后枚举计算。玄学信仰下过掉 1000

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int read()
{
	int a = 0,x = 1;char ch = getchar();
	while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
	while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
	return a*x;
}
const int N=1e3+7;

int dis[N][N];

int n;
int head[N],go[N<<1],nxt[N<<1],cnt;
void add(int u,int v)
{
	go[++cnt] = v;
	nxt[cnt] = head[u];
	head[u] = cnt;
}

void dfs(int u,int fa,int* f) 
{
	if(fa) f[u] = f[fa]+1;
	for(int e = head[u];e;e = nxt[e]) {
		int v = go[e];
		if(v == fa) continue;
		dfs(v,u,f);
	}
}

long long ans = 0;

int main()
{
	freopen("dist.in","r",stdin);
	freopen("dist.out","w",stdout);
	n = read();
	for(int i = 1;i < n;i ++) {
		int u = read(),v = read();
		add(u,v);add(v,u);
	}
	for(int i = 1;i <= n;i ++) {
		dfs(i,0,dis[i]);
	}
	for(int i = 1;i <= n;i ++) {
		for(int j = i+1;j <= n;j ++) {
			for(int k = j+1;k <= n;k ++) {
				ans += min(dis[i][j],min(dis[i][k],dis[j][k]));
			}
		}
	}
	printf("%lld",ans);
	return 0;
}

T3

对于 \(m \leq 100\) 使用 DP ,并使用矩阵快速幂进行加速

对于 \(m+1\) 是 2 的整数幂,计算得出每种或和的方案数。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long

using namespace std;

int read()
{
	int a = 0,x = 1;char ch = getchar();
	while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
	while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
	return a*x;
}
const int N=1e6+7,P=998244353;
int n,m,p;

int calc(int s)
{
	int ret = 0;
	while(s) s -= s&-s,ret ++;
	return ret;
}

int fpow(int a,int x,int q)
{
	if(x == 0) return 1;
	if(x == 1) return a%q;
	int t = fpow(a,x/2,q);
	if(x&1) return t*t%q*a%q;
	else return t*t%q;
}

void MOD(int &a)
{
	if(a>=P) a -= (a/P)*P;
}

struct node{
	int n,m;
	int a[520][520];
	void clear() {n = m = 0;memset(a,0,sizeof(a));}
	friend node operator * (node a,node b)
	{
		node ret;
		ret.clear();
	//	printf("! !\n");
		ret.m = a.m,ret.n = b.n;
		for(int i = 0;i <= ret.n;i ++) {
			for(int j = 0;j <= ret.m;j ++) {
				for(int k = 0;k <= a.n;k ++) {
					MOD(ret.a[i][j] += a.a[k][j]*b.a[i][k]);
				}
			}
		}
//		printf("^_^\n");
		return ret;
	}
};


node qpow(node a,int x)
{
	node tmp = a,ret = a;
	x --;
	while(x){
		if(x&1) ret = ret*tmp;
		tmp = tmp*tmp;
		x >>= 1;
//		printf("%lld\n",x);
	}
	return ret;
}
int f[35];

void subtask()
{
	int ans = 0;
	int qwq = fpow(2,n,P)-1;
	f[0] = 1;
	for(int i = 1;i <= 30;i ++) MOD(f[i] = f[i-1]*qwq);
	for(int i = 0;i <= m;i ++) {
		int len = calc(i);
		MOD(ans += f[len]*fpow(p,i,P));
	//	printf("%d %d\n",i,fpow((fpow(2,n,P)-1),len,P));
	}
	printf("%lld",ans);
}

signed main()
{
	freopen("or.in","r",stdin);
	freopen("or.out","w",stdout);
	n = read(),m = read(),p = read();
	if((m&(m+1)) == 0) {subtask();return 0;}
	node b;b.clear();
	int M=0;
	while(M<m) M = M<<1|1;
	b.n = b.m = M;
	for(int i = 0;i <= M;i ++) {
		for(int j = 0;j <= m;j ++) {
			b.a[i|j][i] ++;
		}
	}
//	b.print();
	node I = qpow(b,n);
	node a;a.clear();
	a.n = m,a.m = 0;
	a.a[0][0] = 1;
	int ans = 0,qwq = 1;
	for(int i = 0;i <= M;i ++) {
		MOD(ans += qwq*I.a[i][0]);
		MOD(qwq *= p);
	}
	printf("%lld",ans);
	return 0;
	
}

T4

直接爆搜

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N=1e6+7;

int p[N],vis[N];
int n,t[N];

void check()
{
	for(int i = 1;i <= n;i ++) {
		if(p[p[i]] != i) return;
	}
	int tmp = 0;
	for(int i = 1;i <= n;i ++) {
		for(int j = 1+i;j <= n;j ++) {
			if(p[j] < p[i]) tmp ++;
		}
	}
	t[tmp] ++;
}

void dfs(int s)
{
	if(s == n+1) {check();return;}
	for(int i = 1;i <= n;i ++) {
		if(vis[i]) continue;
		if(i < s) {
			if(p[i] != s) continue;
		}
		p[s] = i;vis[i] = 1;
		dfs(s+1);vis[i] = 0;
	}
}

int read()
{
	int a = 0,x = 1;char ch = getchar();
	while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
	while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
	return a*x;
}
int k;
int main()
{
	freopen("perm.in","r",stdin);
	freopen("perm.out","w",stdout);
	n = read(),k = read();
	dfs(1);
	for(int i = 0;i < k;i ++) printf("%d",t[i]%2);
	return 0;
}
posted @ 2020-11-26 13:15  nao-nao  阅读(87)  评论(0编辑  收藏  举报