AtCoder Beginner Contest 160题解

A. 签到题1。

#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
    return res*f;
}

const int MAXN = 200'005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int main(){
    string s;cin>>s;
    int ok1=s[2]==s[3];
    int ok2=s[4]==s[5];

    if(ok1&&ok2)cout<<"Yes";
    else cout<<"No";

    return 0;
}
View Code

B. 签到题2。

#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
    return res*f;
}

const int MAXN = 200'005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int main(){
    int x;x=read();
    int ans=(x/500)*1000;
    ans+=(x-(x/500)*500)/5*5;
    cout<<ans;

    return 0;
}
View Code

C. 题意,给你一个环和一些点,可以从任意一个点出发,走遍所有点最短路程。

  显然可以丢弃一段,枚举是哪一段即可。

#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
    return res*f;
}

const int MAXN = 200'005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int k, n;
int A[MAXN];

int main(){
    k=read();n=read();

    for(int i=0;i<n;++i)A[i]=read();

    int mx=0;

    for(int i=0;i<n;++i){
        if(i==n-1){
            mx=max(mx,k-A[n-1]+A[0]);
        }else{
            mx=max(mx,A[i+1]-A[i]);
        }
    }

    cout<<k-mx;

    return 0;
}
View Code

D. 题意,给一条链,和一条额外的边,问长度为1:N-1的最短路有多少条?

  O(n^2)枚举。

#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
    return res*f;
}

const int MAXN = 2'005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int ans[MAXN];

int main(){
    int n, x, y;
    n=read();x=read();y=read();

    for(int i=1;i<=n;++i){
        for(int j=i+1;j<=n;++j){
            int t=min(j-i,1+abs(i-x)+abs(j-y));
            ++ans[t];
        }
    }

    for(int i=1;i<=n-1;++i){
        cout<<ans[i]<<endl;
    }

    return 0;
}
View Code

E. 要吃掉X个红苹果,Y个绿苹果,还有c个无色的苹果,每一个都有一定的价值,问最后最大价值?

  分别排序之后,把前X大和前Y大的丢进堆里,对无色的正向扫,当堆顶部的小于无色的价值时出堆。

#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
    return res*f;
}

const int MAXN = 200'005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int a,b,c;

int x,y;

int A[MAXN], B[MAXN], C[MAXN];

priority_queue<int,vector<int>, greater<int>> q;

int main(){
    x=read();y=read();
    a=read();b=read();c=read();

    for(int i=1;i<=a;++i)A[i]=read();
    for(int i=1;i<=b;++i)B[i]=read();
    for(int i=1;i<=c;++i)C[i]=read();

    sort(A+1,A+1+a);
    sort(B+1,B+1+b);
    sort(C+1,C+1+c);

    LL ans=0;

    for(int i=a;i>=a-x+1;--i)q.push(A[i]), ans+=A[i];
    for(int i=b;i>=b-y+1;--i)q.push(B[i]), ans+=B[i];

    for(int i=c;i>=1;--i){
        if(C[i]>q.top()){
            ans-=q.top();
            q.pop();
            q.push(C[i]);
            ans+=C[i];
        }
    }

    cout<<ans;

    return 0;
}
View Code

F. 给你一颗n个节点的树,依次放入1-n,放置的条件是这条边的另一个点已经放置了数字,求把1分别放置在节点1-n的方案数。

  因为要求把1放在1-n号节点上的方案数,明示了换根dp(或许还有其他做法,但我不会嘿嘿。先考虑以把1放在一号节点的时候怎么数操作数。

  设pre[v]是以v为根的子树的安排方式数。这个时候就是一个简单的乘法原理,先选再放进子树安排。第一次dfs就能处理出所有的pre[]。在换根的时候

  我们首先要考虑到以u的儿子v为根的时候,我们首先要得到u作为v子树的pre[u]。这个显然(可能需要在纸上稍微写一下,原理就是先选再排)是ans[u]/(pre[v]*C(n-1,sz[v])),知道这个之后,得到ans[v]不过就是为u

  这个子树重新选取一些数字而已,这个显然是C(n-1,n-sz[v])种可能。根据计算u答案的方法,直接套用到v上即可,具体见代码。

#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
    return res*f;
}

const int MAXN = 200'005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

#define go(e,u) for(int e=head[u];e;e=Next[e])
int to[MAXN<<1],Next[MAXN<<1],head[MAXN],tol;

void add_edge(int u,int v){
    Next[++tol]=head[u];to[tol]=v;head[u]=tol;
    Next[++tol]=head[v];to[tol]=u;head[v]=tol;
}

int ans[MAXN];

int cnt[MAXN], pre[MAXN], tp[MAXN];

int sz[MAXN];

int fac[MAXN], inv[MAXN], n;

int powmod(int x, int y){
    int res=1;
    while(y){
        if(y&1)res=1ll*res*x%MOD;
        y>>=1;
        x=1ll*x*x%MOD;
    }

    return res%MOD;
}

void init(){
    fac[1]=fac[0]=1;
    for(int i=2;i<=n;++i)fac[i]=1ll*fac[i-1]*i%MOD;
    inv[0]=inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=1ll*MOD-1ll*MOD/i*inv[MOD%i]%MOD;
    for(int i=2;i<=n;++i)inv[i]=1ll*inv[i-1]*inv[i]%MOD;
}

int C(int n, int m){
    return 1ll*fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}

void dfs1(int u, int f){
    sz[u]=1;pre[u]=1;
    go(e,u){
        int v=to[e];
        if(v==f) continue;
        dfs1(v,u);
        sz[u]+=sz[v];
        pre[u]=1ll*pre[u]*pre[v]%MOD*C(sz[u]-1,sz[v])%MOD;
    }
}

void dfs2(int u, int f){
    ans[u]=1ll*tp[u]*pre[u]%MOD*C(n-1,n-sz[u])%MOD;
    go(e,u){
        int v=to[e];
        if(v==f)continue;
        tp[v]=1ll*ans[u]*powmod(1ll*pre[v]*C(n-1,sz[v])%MOD,MOD-2)%MOD;
        dfs2(v,u);
    }
}

int main(){
    n=read();
    for(int i=1;i<n;++i){
        int u, v;
        u=read();
        v=read();
        add_edge(u,v);
    }

    init();
    dfs1(1,0);
    tp[1]=1;
    dfs2(1,0);

    for(int i=1;i<=n;++i)cout<<ans[i]<<endl;

    return 0;
}
/*
8
1 2
2 3
3 4
3 5
3 6
6 7
6 8


40
280
840
120
120
504
72
72

*/
View Code

 

posted @ 2020-03-29 12:09  John_Ran  阅读(243)  评论(0编辑  收藏  举报