A
1 n=1 的情况,只有 m 种符合情况的排列方法。
2 m=1 n>1 的情况,没有符合情况的排列方法。
3 m>1 n>1 的情况,有 m*(m-1)^(n-1) 种符合情况的排列方法。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100000+100;
const ll mod=1e9+7;
ll mypow(ll a,ll b){
ll sum=1;
while(b){
if(b&1) sum=sum*a%mod;
a=a*a%mod;
b>>=1;
}
return sum;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
if(n==1){
printf("%d",m);
}
else if(m==1) printf("0\n");
else{
printf("%lld\n",m*mypow(m-1,n-1)%mod);
}
}
B
仔细想一想,挺简单的,最少的秒数就是最多结点数的以根的孩子结点为根的子树。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000000+100;
int head[maxn],tot;
struct Edge{
int to,next;
}edge[maxn<<1];
int son[maxn];
int Max;
void DFS(int u,int fa){
son[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next){
Edge e=edge[i];
int v=e.to;
if(v==fa) continue;
DFS(v,u);
son[u]+=son[v];
if(u==1) Max=max(Max,son[v]);
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) head[i]=-1;
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
edge[tot].to=u;
edge[tot].next=head[v];
head[v]=tot++;
}
DFS(1,-1);
printf("%d\n",Max);
}
C
水题,具体看代码。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000000+100;
int a[maxn],atot;
int b[maxn],btot;
char str[maxn];
int main(){
int n,m;
scanf("%d%d",&n,&m);
getchar();
scanf("%s",str);
for(int i=0;i<n;i++){
if(str[i]=='B') a[++atot]=i+1;
else b[++btot]=i+1;
}
while(m--){
char tmp;
int k;
getchar();
scanf("%c %d",&tmp,&k);
if(tmp=='B' && k>atot) printf("-1\n");
else if(tmp=='B') printf("%d\n",a[k]);
else if(k>btot) printf("-1\n");
else printf("%d\n",b[k]);
}
}
D
求到根结点最远的距离即可
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=50000+100;
int head[maxn],tot;
struct Edge{
int to,next;
}edge[maxn];
int dis[maxn],len[maxn];
int du[maxn];
int Max;
void DFS(int u,int fa){
for(int i=head[u];i!=-1;i=edge[i].next){
Edge e=edge[i];
int v=e.to;
if(v==fa) continue;
dis[v]=dis[u]+len[v];
DFS(v,u);
Max=max(Max,dis[v]);
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) head[i]=-1;
for(int i=1;i<n;i++){
int u,v,leng;
scanf("%d%d%d",&u,&v,&leng);
edge[tot].to=u;
edge[tot].next=head[v];
head[v]=tot++;
len[u]=leng;
du[u]++;
}
int root;
for(int i=1;i<=n;i++) if(du[i]==0) root=i;
dis[root]=0;
DFS(root,-1);
printf("%d\n",Max);
}
E
先建图,跑一遍最短路即可
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int maxn=10000+100;
const int INF=0x3f3f3f3f;
int head[maxn],tot;
struct Edge{
int to,next,len;
}edge[maxn<<1];
int dis[maxn];
bool vis[maxn];
void Dijkstra(){
dis[0]=0;
priority_queue<P,vector<P>,greater<P> >que;
que.push(P(0,0));
while(!que.empty()){
P p=que.top();
que.pop();
int u=p.second;
if(vis[u]) continue;
for(int i=head[u];i!=-1;i=edge[i].next){
Edge e=edge[i];
int v=e.to;
if(!vis[v] && dis[v]>dis[u]+e.len){
dis[v]=dis[u]+e.len;
que.push(P(dis[v],v));
}
}
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) head[i]=-1,vis[i]=false,dis[i]=INF;
for(int i=0;i<n;i++){
edge[tot].to=i+1;
edge[tot].len=1;
edge[tot].next=head[i];
head[i]=tot++;
edge[tot].to=i;
edge[tot].len=1;
edge[tot].next=head[i+1];
head[i+1]=tot++;
}
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
edge[tot].to=v;
edge[tot].len=1;
edge[tot].next=head[u];
head[u]=tot++;
}
Dijkstra();
printf("%d\n",dis[n]);
}
F
完全背包,竟然这么水。。。
这次没有难题,我竟然能AK,是什么鬼!!!
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+100;
const int mod=19260817;
int dp[maxn],ans[maxn];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&ans[i]);
dp[0]=1;
for(int i=1;i<=n;i++){
for(int j=ans[i];j<=m;j++) dp[j]=(dp[j]+dp[j-ans[i]])%mod;
}
int sum=0;
for(int i=1;i<=m;i++) sum=(sum+dp[i])%mod;
printf("%d\n",sum);
}