Codeforces Round #177 (Div. 1) 题解【ABCD】
Codeforces Round #177 (Div. 1)
A. Polo the Penguin and Strings
题意
让你构造一个长度为n的串,且里面恰好包含k个不同字符,让你构造的字符串字典序最小。
题解
先abababab,然后再把k个不同字符输出,那么这样就是最少
代码
#include<bits/stdc++.h>
using namespace std;
string s;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
if(n>1&&k==1){
cout<<"-1"<<endl;
return 0;
}
if(k>n){
cout<<"-1"<<endl;
return 0;
}
if(k==1){
for(int i=1;i<=n;i++)
printf("a");
}else{
for(int i=0;i<n-k+2;i++){
if(i%2==0)printf("a");
else printf("b");
}
for(int i=2;i<k;i++)
printf("%c",'a'+i);
}
printf("\n");
}
B. Polo the Penguin and Houses
题意
给你n个城市,你在x城市,那么下一步会走到a[x]城市。
现在你从前k个城市出发,最终都会走到1号点,从后面n-k个城市出发,不会走到1节点,问你一共有多少种方案。
题解
k很小,所以直接dfs就好了,可以先预处理一下一些没必要dfs的部分。
代码
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int n,k,cnt=0;
int a[10],flag,vis[10];
long long ans = 0;
int dfs2(int x){
if(x==1)return 1;
if(vis[x])return 0;
vis[x]=1;
dfs2(a[x]);
}
void check()
{
flag=1;
for(int i=2;i<=k&&flag;i++){
memset(vis,0,sizeof(vis));
flag&=dfs2(i);
}
if(flag)cnt++;
}
void dfs(int x){
if(x==k+1){
check();
return;
}
for(int i=1;i<=k;i++)
a[x]=i,dfs(x+1);
}
int main()
{
scanf("%d%d",&n,&k);
ans=k;
for(int i=0;i<n-k;i++)
ans=(ans*(n-k))%mod;
dfs(2);
cout<<(ans*1ll*cnt)%mod<<endl;
}
C - Polo the Penguin and XOR operation
题意
让你构造一个排列,使得sigma(i^a[i])最大
题解
手动玩一玩可以发现,实际上是可以异或互补的,所以我们把那些互补的都给补上,答案就是最大的。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
int vis[maxn],n,a[maxn],ans[maxn];
int main(){
scanf("%d",&n);
for(int i=n;i>=0;i--){
if(vis[i])continue;
int tmp=i,len=0;
while(tmp){
tmp/=2;
len++;
}
int Up=(1<<len)-1;
int x2=Up^i;
ans[i]=x2;
ans[x2]=i;
vis[i]=vis[x2]=1;
}
long long Ans = 0;
for(int i=0;i<=n;i++)
Ans+=i^ans[i];
cout<<Ans<<endl;
for(int i=0;i<=n;i++)
cout<<ans[i]<<" ";
cout<<endl;
}
288D - Polo the Penguin and Trees
题意
给你一棵树,问你有多少对不相交路径
题解
反过来做,然后容斥搞一搞,减去相交的对数。
分为子树外和子树内,都扣一扣就好了
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 8e4+6;
int n;
long long s[maxn];
long long ans = 0;
vector<int> E[maxn];
void dfs(int x,int f){
s[x]=1;
long long tmp = 0;
for(int i=0;i<E[x].size();i++){
int v=E[x][i];
if(v==f)continue;
dfs(v,x);
tmp+=1ll*s[x]*s[v];
s[x]+=s[v];
}
ans-=1ll*tmp*(tmp+2LL*s[x]*(n-s[x]));
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
E[a].push_back(b);
E[b].push_back(a);
}
ans=1ll*n*(n-1LL)/2LL*(n*(n-1LL)/2LL);
dfs(1,0);
cout<<ans<<endl;
}