• 10.28 考试


    T1

    好水啊~~~

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int N=100006;
    int first[N],nt[N*2],ver[N*2],e;
    void addbian(int u,int v)
    {
        ver[e]=v;
        nt[e]=first[u];
        first[u]=e++;
    }
    
    int n,an;
    
    int fa[N],xi[N],id[N];
    void dfs(int x)
    {
        xi[x]=1;
        int i;
        for(i=first[x];i!=-1;i=nt[i])
        {
            if(ver[i]==fa[x])
                continue;
            fa[ver[i]]=x;
            id[ver[i]]=(i>>1)+1;
            dfs(ver[i]);
            xi[x]+=xi[ver[i]];
        }
    }
    
    int main(){
        
        //freopen("T1.in","r",stdin);
        
        //freopen("div.in","r",stdin);
        //freopen("div.out","w",stdout);
        
        rint i;
        
        mem(first,-1);
        
        read(n);
        int tin1,tin2;
        for(i=1;i<n;++i)
        {
            read(tin1); read(tin2);
            addbian(tin1,tin2);
            addbian(tin2,tin1);
        }
        dfs(1);
        an=-1;
        for(i=1;i<=n;++i)
            if(id[i]&&xi[i]*2==n)
                an=id[i];
        cout<<an;
        fclose(stdin);
        fclose(stdout);
    }
    T1

    T2

    题解释哈夫曼树,然而我并不是这样想的...

    可以考虑在01trie上行走

    那么它一定是在每一个深度都用完了,在到下一层

    可以脑补一下...

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int N=10000006;
    const int mod=1000000007;
    
    ll qpow(ll a,int ci)
    {
        ll ans=1;
        while(ci)
        {
            if(ci&1)
                ans=ans*a%mod;
            a=a*a%mod;
            ci>>=1;
        }
        return ans;
    }
    
    int n;
    
    ll jie[N],jieni[N];
    void chu()
    {
        int i;
        
        jie[0]=1;
        for(i=1;i<N;++i) jie[i]=jie[i-1]*i%mod;
        jieni[N-1]=qpow(jie[N-1],mod-2)%mod;
        for(i=N-2;i>=1;--i)
            jieni[i]=jieni[i+1]*(i+1)%mod;
        jieni[0]=1;
    }
    
    ll C(int n,int m)
    {
        if(n<0||m<0||n<m) return 0;
        return jie[n]*jieni[m]%mod*jieni[n-m]%mod;
    }
    
    int main(){
        
        //freopen("str.in","r",stdin);
        //freopen("str.out","w",stdout);
        
        chu();
        
        read(n);
        int k=0;
        while((1<<k)<=n) ++k; --k;
        printf("%lld",C((1<<k),(n-(1<<k)))%mod*jie[n]%mod );
        fclose(stdin);
        fclose(stdout);
    }
    T2

    T3

    (1)

    你可以大暴搜

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int N=5006;
    const int mod=1000000007;
    
    int n,K;
    int ans;
    
    void dfs(int order,int now,int mn,int mx)
    {
        if(mx-mn>K)
            return ;
        if(order==n+1)
        {
            ++ans;
            return ;
        }
        dfs(order+1,now+1,mn,max(mx,now+1));
        dfs(order+1,now+2,mn,max(mx,now+2));
        dfs(order+1,now-1,min(mn,now-1),mx);
    }
    
    int main(){
        
        //freopen("T3.in","r",stdin);
        
        read(n); read(K);
        dfs(1,0,0,0);
        cout<<ans;
    }
    1

    (2)

    $O(nK^3)$的dp

    $f_{i,j,k,v}$ 表示当前走到了第i个位置,最大值是j,最小值是k,当前的权值是v的方案数

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int N=5006;
    const int mod=1000000007;
    const int BAO=78;
    
    int n,K;
    ll f[2][BAO*3][BAO][BAO*2];
    
    ll dp()
    {
        rint i,j,k,p;
        int now=1,mn=BAO-n,mx=n+n+BAO,nx,tmx,tt;
        //printf("mn=%d mx=%d
    ",mn,mx);
        mem(f,0);
        f[0][BAO][BAO][0]=1;
        for(i=0;i<n;++i)
        {
            now^=1; nx=now^1;
            mem(f[nx],0);
            for(j=mn;j<=mx;++j)
                for(k=BAO-i;k<=j;++k)
                    for(p=max(j,BAO);p<=mx;++p)
                        if(f[now][j][k][p-BAO])
                        {
                            //printf("i=%d
    ",i);
                            tmx=p-BAO; tt=f[now][j][k][tmx];
                            f[nx][j+1][k][max(tmx,j+1-BAO)]+=tt; f[nx][j+1][k][max(tmx,j+1-BAO)]%=mod;
                            f[nx][j+2][k][max(tmx,j+2-BAO)]+=tt; f[nx][j+2][k][max(tmx,j+2-BAO)]%=mod;
                            f[nx][j-1][min(j-1,k)][tmx]+=tt; f[nx][j-1][min(j-1,k)][tmx]%=mod;
                        }
        }
        ll ans=0;
        for(i=mn;i<=mx;++i)
            for(j=mn;j<=BAO;++j)
            {
                tt=min(j+K,mx);
                for(k=j;k<=tt;++k)
                    ans=(ans+f[nx][i][j][k-BAO])%mod;
            }
        return ans;
    }
    
    int main(){
        
        freopen("T3.in","r",stdin);
        
        read(n); read(K);
        printf("%lld",dp());
    }
    2

    (3)

    $O(nK^2)$ 的dp

    $f_{i,j,k}$ 表示当前走到了第i个位置,最大值和最小值的差值是j,当前值比最小值大k的方案数

    特别的,差值j是当前走的路线到过了最大值和最小值才行,所以不会重复

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int mod=1000000007;
    
    int n,K;
    ll f[2][306][306];
    
    ll dp()
    {
        int i,j,k,tt,now=1,nx,nj,nk; ll ans=0;
        f[0][0][0]=1;
        for(i=0;i<n;++i)
        {
            now^=1; nx=now^1;
            mem(f[nx],0);
            for(j=0;j<=2*i&&j<=K;++j)
                for(k=0;k<=j;++k)
                    if(f[now][j][k])
                    {
                        nk=k+1; nj=j; if(nj<nk) nj=nk;
                        if(nj<=K) f[nx][nj][nk]=(f[nx][nj][nk]+f[now][j][k])%mod;
                        nk=k+2; nj=j; if(nj<nk) nj=nk;
                        if(nj<=K) f[nx][nj][nk]=(f[nx][nj][nk]+f[now][j][k])%mod;
                        nk=k-1; nj=j; if(nk<0) nj=nj-nk,nk=0;
                        if(nj<=K) f[nx][nj][nk]=(f[nx][nj][nk]+f[now][j][k])%mod;
                    }
        }
        for(i=0;i<=K;++i)
            for(j=0;j<=i;++j)
                ans=(ans+f[nx][i][j])%mod;
        return ans%mod;
    }
    
    int main(){
        
        read(n); read(K);
        printf("%lld",dp());
    }
    3

    (4)

    $O(nK)$ 的dp

    我们考虑在一个n*K大小的网格里从最左边往右走

    枚举起点在最左边的位置,就相当于枚举最小值

    $f_{i,j,k}$ 表示当前走到了第i个位置,当前的权值是j,到没到过0(也就是最小值)的方案数

    这样开第三维也可以保证不重复

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int mod=1000000007;
    
    int n,K;
    ll f[2][5006][2];
    
    ll dp()
    {
        int i,j,k,tt,now=1,nx; ll ans=0;
        f[0][0][1]=1;
        for(i=1;i<=K;++i) f[0][i][0]=1;
        for(i=0;i<n;++i)
        {
            now^=1; nx=now^1;
            mem(f[nx],0);
            for(j=0;j<=K;++j)
            {
                tt=j+1;
                if(tt<=K) f[nx][tt][0]=(f[nx][tt][0]+f[now][j][0])%mod,f[nx][tt][1]=(f[nx][tt][1]+f[now][j][1])%mod;
                tt=j+2;
                if(tt<=K) f[nx][tt][0]=(f[nx][tt][0]+f[now][j][0])%mod,f[nx][tt][1]=(f[nx][tt][1]+f[now][j][1])%mod;
                tt=j-1;
                if(tt>0) f[nx][tt][0]=(f[nx][tt][0]+f[now][j][0])%mod,f[nx][tt][1]=(f[nx][tt][1]+f[now][j][1])%mod;
                else if(tt==0) f[nx][tt][1]=(f[nx][tt][1]+f[now][j][0]+f[now][j][1])%mod;
            }
        }
        for(i=0;i<=K;++i)
            ans=(ans+f[nx][i][1])%mod;
        return ans%mod;
    }
    
    int main(){
        
        read(n); read(K);
        printf("%lld",dp());
    }
    4
  • 相关阅读:
    asp.net性能的技巧
    『笔记』数学数论(二)
    『笔记』数学数论(五)
    『笔记』数学数论(一)
    『笔记』数学数论(四)
    『笔记』分块与块状数组
    『笔记』矩阵
    『题解』CF28A Bender Problem
    『笔记』数学数论(七)
    『笔记』数学数论(三)
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7748191.html
Copyright © 2020-2023  润新知