比上次多做了一道,但排名退了600,确实题比较水......
ABCDE几乎都算水题,C是一个类似秦九韶算法的东西,在26进制下搞一下即可,第一波搞忘减去余数还WA了......D利用“同一个数跟自己异或偶数次为0”的性质也很容易整出来,说一下F这道计数题。
题意很简单,问在一个给定的长为m的原字符串的基础上插入(可以插在串头和串尾)n个新字符能得到多少种新串,要做到不重复计数有一定难度。
最直接的思路就是n+m个位置上选m个位置放入原字符串的字符然后剩下的随便填,但很容易发现这么算会算重,比如aabb和aabb是等价的但是会算两次。
于是考虑如何去重,我们让在串头插入的若干个元素随便填,然后让中间插入的元素,比如在第i个原字符之后插入的字符,不与第i个字符相同,这样做的原因是:如果能插入相同字符,那么得到的串一定可以通过调整之前插入的字符得到。比如aaaaabab等价于aaaaabab,abcbdbsbd等价于abcbdbsbd。所以在枚举中间和串尾插入的字符时只有25种选择而非26(开头插入的字符的选法为26)。所以,在新串的n+m个位置上,枚举一下开头插入的字符个数i(0<=i<=n),有26的i次方种选法,(然后将第一个原字符紧接着放入第i+1位)再乘上剩下m-1个原字符在n+m-i-1个位置上选位置的选法(组合数计算),再乘上剩下中间和串尾的待定字符的选法(25的n-i次方)。
求组合数时线性递推预处理一下阶乘和阶乘逆元即可。
P.S. 上述去重的过程也说明了答案只跟原串的长度有关,跟原串的字符无关,比如对于同一个n,"aaa"和"abc"的答案是一样的。官方题解说这一点很intuitive,可能是我菜了......并不觉得这很明显QAQ...
A题
#include
#include
#include
#include
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
#include
#include
#include
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
#include
#include
#include
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
#include
#include
#include
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
E题
#include
#include
#include
#include
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
#include
#include
#include
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;
}