# 「2017 Multi-University Training Contest 1」2017多校训练1

### 1001 Add More Zero（签到题）

#include <cstdio>
#include <cmath>
int cas,m;
int main(){
while(~scanf("%d",&m)){
printf("Case #%d: %d\n",++cas,(int)(m*log(2)/log(10)));
}
return 0;
}

### 1002 Balala Power!（贪心）

#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 100005
#define M 26

using namespace std;
typedef long long ll;
const ll MOD=(1e9+7);

struct Node{
int id;
int big;
bool zero;
}zm[M];

ll p[N];
ll k[M][N];
char s[N];
int cas,n;

void init(){
p[0]=1;
for(int i=1;i<N;++i)p[i]=p[i-1]*M%MOD;
}
bool cmp(const Node& a,const Node& b){
if(a.big==b.big){
int i;
for(i=a.big;i&&k[a.id][i]==k[b.id][i];--i);
return k[a.id][i]<k[b.id][i];
}
return a.big<b.big;
}
ll solve(){
for(int i=0;i<M;++i){
for(int j=0;j<=zm[i].big;++j){
if(k[i][j]>=M){
k[i][j+1]+=k[i][j]/M;
k[i][j]%=M;
if(j==zm[i].big)++zm[i].big;//！！！
}
}
}
sort(zm,zm+M,cmp);

ll ans=0;
int i;
for(i=0;i<M&&!zm[i].zero;++i);
rotate(zm,zm+i,zm+i+1);
for(int i=0;i<M;++i){
for(int j=0;j<=zm[i].big;++j){
ans+=k[zm[i].id][j]*p[j]*i;
if(ans>=MOD)ans%=MOD;
}
}
return ans;
}
int main(){
init();
while(~scanf("%d",&n)){
for(int i=0;i<M;++i){
zm[i].id=i;
zm[i].big=0;
zm[i].zero=true;
memset(k[i],0,sizeof(k[i]));
}
for(int i=0;i<n;++i){
scanf("%s",s);
int len=strlen(s);
if(len>1)zm[s[0]-'a'].zero=false;
for(int j=0;s[j];++j){
int d=s[j]-'a';
++k[d][len-j-1];
zm[d].big=max(zm[d].big,len-j-1);
}
}
printf("Case #%d: %lld\n",++cas,solve());
}
return 0;
}

### 1003 Colorful Tree（dfs）

#include <bits/stdc++.h>
#define N 200001
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;

int n;
vector<int> e[N];
int siz[N];
int col[N];
ll sum[N];
ll ans;
void dfs(int u,int f){
siz[u]=1;
ll tot=0;
for(auto v:e[u]){
if(v!=f){
ll prev = sum[col[u]];
dfs(v,u);
siz[u] += siz[v];
ll sumv = sum[col[u]] - prev;
ll othr = siz[v] - sumv;
tot += sumv;
ans -= (othr-1)*othr/2;
}
}
sum[col[u]]+=siz[u]-tot;
}
int cas;
int cnt;
bool mark[N];
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;++i){
e[i].clear();
mark[i]=0;
sum[i]=0;
cnt=0;
}
for(int i=1;i<=n;++i){
scanf("%d",&col[i]);
if(!mark[col[i]]){
mark[col[i]]=1;
++cnt;
}
}
for(int i=1;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
e[u].pb(v);
e[v].pb(u);
}
ans=(ll)n*(n-1)/2*cnt;
dfs(1,0);
for(int i=1;i<=n;++i)
if(sum[i]){
ll up=n-sum[i];
ans-=(up-1)*up/2;
}
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}

### 1006 Function（置换）

#include <cstdio>
#include <cstring>
#define mem(a,b) memset(a,b,sizeof(a))
#define N 100001
typedef long long ll;
const ll MOD =1e9+7;
int n,m,cas;
int a[N],b[N],len[N];
bool vis[N];

int main() {
int n,m;
while(~scanf("%d%d",&n,&m)) {
mem(len,0);
mem(vis,0);
for(int i=0; i<n; ++i)
scanf("%d",a+i);
for(int j=0; j<m; ++j)
scanf("%d",b+j);
for(int i=0; i<m; ++i)
if(!vis[i]) {
int t=b[i];
int l=1;
while(t!=i) {
vis[t]=true;//！！
t=b[t];
++l;
}
++len[l];
}
mem(vis,0);
ll ans=1;
for(int i=0; i<n; ++i)
if(!vis[i]) {
int t=a[i];
int l=1;
while(t!=i) {
vis[t]=true;
t=a[t];
++l;
}
ll res=0;
for(int j=1; j*j<=l; ++j)
if(l%j==0) {
if(j*j!=l) res+=(ll)l/j*len[l/j];//！！！
res+=(ll)j*len[j];
res%=MOD;
}
ans=ans*res%MOD;
}
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}

### 1011 KazaQ‘s Socks（找规律）

#include <cstdio>
long long n,k;
int t;
int main(){
while(~scanf("%lld%lld",&n,&k)){
printf("Case #%d: ",++t);
if(k<=n)printf("%lld\n",k);
else{
k-=n;
if(k%(n-1))
printf("%lld\n",k%(n-1));
else if((k/(n-1))%2)
printf("%lld\n",n-1);
else
printf("%lld\n",n);
}
}
return 0;
}

### 1012 Limited Permutation（递归）

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cctype>
#include <map>
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 1000001;
const LL MOD =1e9+7;

char buf[100000],*p1=buf,*p2=buf;
inline char nc(){
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline bool rea(int & x){
char c=nc();x=0;
if(c==EOF) return false;
for(;!isdigit(c);c=nc());
for(;isdigit(c);x=x*10+c-'0',c=nc());
return true;
}
inline bool rea(LL & x){
char c=nc();x=0;
if(c==EOF) return false;
for(;!isdigit(c);c=nc());
for(;isdigit(c);x=x*10+c-'0',c=nc());
return true;
}

int cas;
int n;
int l[N];
map<PII,int> mm;
LL fac[N],inv[N];
LL qpow(LL a,LL b){
LL ans=1;
while(b){
if(b&1)ans=ans*a%MOD;
a=a*a%MOD;
b>>=1;
}
return ans;
}
void init(){
fac[0] = inv[0] =1;
for(int i=1;i<N;++i){
fac[i]=fac[i-1]*i%MOD;
inv[i]=qpow(fac[i],MOD-2);
}
}
LL C(LL n,LL m){
return n<m?0:(fac[n]*inv[m]%MOD)*inv[n-m]%MOD;
}
LL solve(int l,int r){
if(l>r+1)return 0;
if(l==r+1)return 1;
auto it=mm.find(mp(l,r));
if(it==mm.end()){
return 0;
}
int x=it->second;
if(x<l||x>r)return 0;
if(l==r)return 1;

LL ans=solve(l,x-1)*solve(x+1,r)%MOD*C(r-l, x-l)%MOD;
return ans;
}
int main(){
init();
while(rea(n)){
mm.erase(mm.begin(),mm.end());
for(int i=1;i<=n;++i){
rea(l[i]);
}
for(int i=1;i<=n;++i){
int r;
rea(r);
mm[mp(l[i],r)]=i;
}
printf("Case #%d: %lld\n",++cas,solve(1,n));
}
return 0;
}

0 条评论

• ### 「CodeForces - 598B」Queries on a String

字符串s（1 ≤ |s| ≤ 10 000），有m（1 ≤ m ≤ 300）次操作，每次给l,r,k，代表将r位置插入l位置前，执行k（1 ≤ k ≤ 1 00...

• ### 【HDU 5438】Ponds

存边的时候，要头尾都存这个边。用dfs或者队列删点，再用并查集或者dfs确定联通块，然后统计联通块的点数，最后累加。

• ### BZOJ3004: 吊灯(结论 毒瘤)

结论：若$k$是可行的，则至少有$\frac{n}{k}$个节点的大小为$k$的倍数

• ### 1464: [蓝桥杯2019初赛]数的分解

把2019分解成3个各不相同的正整数之和，并且要求每个正整数都不包含数字2和4，一共有多少种不同的分解方法？注意交换3个整数的顺序被视为同一种方法，例如1000...

• ### 挖掘机技术哪家强（c++实现）

描述：为了用事实说明挖掘机技术到底哪家强，组织一场挖掘机技能大赛。现请你根据比赛结果统计出技术最强的那个学校。

• ### 牛客集训派对day3

题目描述 有一张无限大的棋盘，你要将马从(0,0)移到(n,m)。 每一步中，如果马在(x,y)，你可以将它移动到(x+1,y+2),(x+1,y-2),(x-...

• ### 洛谷P5108 仰望半月的夜空(后缀数组)

warning：下面这个做法只有95分，本地拍了1w+组都没找到错误我表示十分无能为力

• ### POJ Test for Job(DAG上拓扑排序)

题意是给了n个点，m条边(单向边)，然后每个点都有一个点权(存在负权)，问从入度为0的点开始到出度为0的点，最大的权值和为多少。

• ### leetcode 204题求素数个数

Count the number of prime numbers less than a non-negative number, n