比赛链接:2017 Multi-University Training Contest 1
A:水
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int m,T=1;
while(~scanf("%d",&m))
{
printf("Case #%d: %d\n",T++,(int)(m*log10(2)));
}
return 0;
}
B:
将所有字符串化成系数*字母的形式,其中系数也用26进制数表示,系数大的赋权大,然后考虑不能有前导零的情况就行了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int N=1e5+7;
int c[26][N],p[26],v[26];
char s[N];
bool zero[26];
bool cmp(int a, int b)
{
for(int i=N-1;i>=0;--i)
if(c[a][i]>c[b][i]) return true;
else if(c[a][i]<c[b][i]) return false;
return false;
}
int main()
{
int n,T=1;
while(~scanf("%d",&n))
{
memset(c,0,sizeof(c));
memset(v,-1,sizeof(v));
memset(zero,false,sizeof(zero));
for(int i=0;i<n;++i)
{
scanf("%s",s);
int m=strlen(s);
if(m>1) zero[s[0]-'a']=true;
for(int j=0;j<m;++j)
++c[s[j]-'a'][m-j-1];
}
for(int i=0;i<26;++i)
for(int j=0;j<N-1;++j)
if(c[i][j]>=26)
{
c[i][j+1]+=c[i][j]/26;
c[i][j]%=26;
}
for(int i=0;i<26;++i) p[i]=i;
sort(p,p+26,cmp);
for(int i=25;i>=0;--i) if(!zero[p[i]]) { v[p[i]]=0; break; }
int cur=25;
for(int i=0;i<26;++i)
if(v[p[i]]!=0) v[p[i]]=cur--;
ll ans=0;
for(int i=0;i<26;++i)
{
ll k=1,res=0;
for(int j=0;j<N;++j)
{
res=(res+k*c[i][j]%mod)%mod;
k=k*26%mod;
}
ans=(ans+v[i]*res%mod)%mod;
}
printf("Case #%d: ",T++);
printf("%I64d\n",ans);
}
return 0;
}
C:
树形dp
F:
bu=v
代表一条有向边
(u,v)
。
根据题目给定的
b
数组可以得到一个仅含环的图
再根据
f(i)=bf(ai)
可以再得到一个图
G2
。
G2
中的环可以被
G1
中的环置换,且求置换的环必须是被置换的环的因子。
因此处理出每种长度环的数量,然后筛一下就行了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int N=1e5+7;
int n,m,p[N];
ll cf[N],cb[N];
bool vis[N];
int main()
{
int T=1;
while(~scanf("%d%d",&n,&m))
{
memset(cf,0,sizeof(cf));
memset(cb,0,sizeof(cb));
for(int i=0;i<n;i++)
{
int u;
scanf("%d",&u);
p[u]=i;
}
memset(vis,0,sizeof(vis));
for(int i=0;i<n;++i)
{
if(!vis[i])
{
int k=0,u=i;
while(!vis[u]) ++k,vis[u]=true,u=p[u];
cf[k]++;
}
}
for(int i=0;i<m;i++)
{
int u;
scanf("%d",&u);
p[i]=u;
}
memset(vis,0,sizeof(vis));
for(int i=0;i<m;++i)
{
if(!vis[i])
{
int k=0,u=i;
while(!vis[u]) ++k,vis[u]=true,u=p[u];
cb[k]++;
}
}
for(int i=n;i>=1;--i)
{
ll k=cb[i];
for(int j=i*2;j<=n;j+=i)
cb[j]=(cb[j]+k*i%mod)%mod;
cb[i]=k*i;
}
ll ans=1;
for(int i=1;i<=n;++i)
while(cf[i]--) ans=ans*cb[i]%mod;
printf("Case #%d: %I64d\n",T++,ans);
}
return 0;
}
H:
H
K:
打表找规律就行了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n,k;
int T=1;
while(~scanf("%I64d%I64d",&n,&k))
{
printf("Case #%d: ",T++);
if(k<=n) printf("%I64d\n",k);
else
{
k-=n;
if((k-1)/(n-1)%2==0)
{
if(k%(n-1)==0) printf("%I64d\n",n-1);
else printf("%I64d\n",(k-1)%(n-1)+1);
}
else
{
if(k%(n-1)==0) printf("%I64d\n",n);
else printf("%I64d\n",(k-1)%(n-1)+1);
}
}
}
}
L:
L