AtCoder Beginner Contest 171 總結

比上次多做了一道,但排名退了600,確實題比較水......

ABCDE幾乎都算水題,C是一個類似秦九韶算法的東西,在26進制下搞一下即可,第一波搞忘減去餘數還WA了......D利用“同一個數跟自己異或偶數次爲0”的性質也很容易整出來,說一下F這道計數題。

題意很簡單,問在一個給定的長爲m的原字符串的基礎上插入(可以插在串頭和串尾)n個新字符能得到多少種新串,要做到不重複計數有一定難度。

最直接的思路就是n+m個位置上選m個位置放入原字符串的字符然後剩下的隨便填,但很容易發現這麼算會算重,比如aabbaabb是等價的但是會算兩次。

於是考慮如何去重,我們讓在串頭插入的若干個元素隨便填,然後讓中間插入的元素,比如在第i個原字符之後插入的字符,不與第i個字符相同,這樣做的原因是:如果能插入相同字符,那麼得到的串一定可以通過調整之前插入的字符得到。比如aaaaabab等價於aaaaabababcbdbsbd等價於abcbdbsbd。所以在枚舉中間和串尾插入的字符時只有25種選擇而非26(開頭插入的字符的選法爲26)。所以,在新串的n+m個位置上,枚舉一下開頭插入的字符個數i(0<=i<=n),有26的i次方種選法,(然後將第一個原字符緊接着放入第i+1位)再乘上剩下m-1個原字符在n+m-i-1個位置上選位置的選法(組合數計算),再乘上剩下中間和串尾的待定字符的選法(25的n-i次方)。

ans=\sum_{i=0}^{n}26^{i}*C_{n+m-i-1}^{m-1}*25^{n-i}

求組合數時線性遞推預處理一下階乘和階乘逆元即可。

P.S. 上述去重的過程也說明了答案只跟原串的長度有關,跟原串的字符無關,比如對於同一個n,"aaa"和"abc"的答案是一樣的。官方題解說這一點很intuitive,可能是我菜了......並不覺得這很明顯QAQ...

 

A題

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

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

int main() {
	char x;
	scanf("%c",&x);
	if (x>='a'&&x<='z') puts("a");
	else puts("A");
	return 0;
}

B題

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+4;
inline int read() {
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*f;
}
int n,m,sum;
int a[N];
int main() {
//	freopen("in.txt","r",stdin);
	n=read(),m=read();
	for (register int i=1;i<=n;++i) a[i]=read();
	sort(a+1,a+n+1);
	for (register int i=1;i<=m;++i) sum+=a[i];
	printf("%d\n",sum);
	return 0;
}

C題

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
inline int read() {
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*f;
}
ll x;
char sta[104];
int tot;
int main() {
//	freopen("in.txt","r",stdin);
	cin>>x;
	while (x) {
		ll cur=x%26;
		if (cur==0) cur=26;
		x-=cur;
		sta[tot++]='a'+cur-1;
		x/=26;
	}
	for (int i=tot-1;~i;--i)
		printf("%c",sta[i]);
	return 0;
}

D題

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+4;
int n,m;
int a[N],b[N];
int cnt[N];
ll sum;
inline int read() {
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*f;
}
int main() {
//	freopen("in.txt","r",stdin);
	n=read();
	for (register int i=1;i<=n;++i) {
		a[i]=read();
		++cnt[a[i]];
		sum+=a[i];
	}
	m=read();
	for (register int i=0;i<m;++i) {
		int x=read(),y=read();
		sum+=1ll*cnt[x]*(y-x);
		cnt[y]+=cnt[x];
		cnt[x]=0;
		printf("%lld\n",sum);
	}
	return 0;
}

E題

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e5+4;
inline int read() {
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*f;
}
int n;
int a[N];
int sum;
int main() {
	freopen("in.txt","r",stdin);
	n=read();
	for (register int i=1;i<=n;++i) {
		a[i]=read();
		sum^=a[i];
	}
	for (register int i=1;i<=n;++i) {
		printf("%d ",sum^a[i]);
	}
	return 0;
}

F題

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e6+4;
const ll MOD=1e9+7;
inline int read() {
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*f;
}
ll fac[N<<1]={1,1};
ll inv[N]={1,1};
int n,m;
char s[N];
inline ll fpow(ll a,int b) {
	ll ret=1;
	while (b) {
		if (b&1) ret=ret*a%MOD;
		b>>=1,a=a*a%MOD;
	}
	return ret;
}
inline ll C(int x,int y) {
	ll ans=fac[x];
	ans=ans*inv[y]%MOD;
	ans=ans*inv[x-y]%MOD;
	return ans;
}
int main() {
//	freopen("in.txt","r",stdin);
	for (register int i=1;i<(N<<1);++i) fac[i]=fac[i-1]*i%MOD;
	inv[N-1]=fpow(fac[N-1],MOD-2);
	for(int i=N-2;~i;--i)
	   inv[i]=inv[i+1]*(i+1)%MOD;
	n=read();
	scanf("%s",s);
	m=strlen(s);
	ll ans=0;
	for (register int i=0;i<=n;++i) {
		ll c=fpow(26,i)*fpow(25,n-i)%MOD;
		(ans+=c*C(n+m-i-1,m-1)%MOD)%=MOD;
	}
	printf("%lld\n",ans);
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章