zoukankan      html  css  js  c++  java
  • 20191023

    前言

    • 改题最快的一次考试……
    • 好久没看到过这么友好的题了,出题人++rp。

    T1

    • 小Q的分数只和最高位的1有关。
    • 直接找就行了,找到就是小Q赢,没找到就是平局。
    • 代码巨短。
    • 时间复杂度$Theta(N)$,空间复杂度$Theta(1)$。
    #include<cstdio>
    int main(){
        int T,n,c,x,y;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n),c=0;
            for(register int i=1;i<=n;++i)scanf("%d",&x),c^=x;
            for(register int i=1;i<n;++i)scanf("%d%d",&x,&y);
            puts(c?"Q":"D");
        }
        return 0;
    }
    View Code

    T2

    • $Theta(N^2)$暴力非常显然,直接枚举中间位置即可。
    • 至于优化……
    • 需要一个非常基础的柿子:$C_n^i=C_n^{n-i}$。
    • 这个柿子很简单,难在想到用它去转化思路。
    • 原本的柿子大约是$sumlimits_{i=0}^n C_n^i+C_m^{i+1}$之类的东西。
    • 然后你把$C_n^i$看成$C_n^{n-i}$,这样n-i和i+1的和就固定了。
    • 又因为$iin[0,n]$,所以这个柿子可以理解成$C_{n+m}^{n+1}$,就可以直接计算了。
    • 时空复杂度$Theta(N)$。
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    int const N=2e5+5,mod=1e9+7;
    int n;
    char s[N];
    int a[N],b[N];
    ll fac[N],inv[N],ans;
    inline int read(){
        int ss(0);char bb(getchar());
        while(bb<48||bb>57)bb=getchar();
        while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
        return ss;
    }
    inline ll power(ll x,int y){
        ll as=1;
        for(;y;y>>=1,x=x*x%mod)
            if(y&1)as=as*x%mod;
        return as;
    }
    inline ll C(int x,int y){
        return fac[x]*inv[y]%mod*inv[x-y]%mod;
    }
    inline int min(int x,int y){
        return x<y?x:y;
    }
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        scanf("%s",s+1);
        n=strlen(s+1);
        for(register int i=1;i<=n;++i)a[i]=a[i-1]+(s[i]=='(');
        for(register int i=n;i;--i)b[i]=b[i+1]+(s[i]==')');
        fac[0]=fac[1]=1;
        for(register int i=2;i<=n;++i)fac[i]=fac[i-1]*i%mod;
        inv[n]=power(fac[n],mod-2);
        for(register int i=n;i;--i)inv[i-1]=inv[i]*i%mod;
        for(register int i=1;i<=n;++i)
            if(s[i]=='(')
                ans=(ans+C(a[i]+b[i]-1,a[i]))%mod;
        printf("%lld",ans);
        return 0;
    }
    View Code

    T3

    • $Theta(N^3K)$的算法应该不难想到。
    • 应该不是Floyd,至少我是先枚举的起点再枚举的中间点。可以直接想出来,不用借助什么算法理解。
    • 正解是考虑分块,算出经过$100 imes k(kin [0,100])$条边的最短距离,再算出至少经过0~100条边的最短距离。
    • 这样10000以内的询问都可以拆成$100 imes a+b$的形式($ain[0,100],bin[0,100)$)。
    • 每次只需$Theta(N)$枚举中间点即可。
    • 设A=100,时间复杂度$Theta(AN^3+QN)$,空间复杂度$Theta(AN^2)$,可以通过此题。
    #include<cstdio>
    #include<cstring>
    #define int long long
    using namespace std;
    int const N=51,lar=0x3f3f3f3f;
    int n,m;
    int dis[152][N][N],f[102][N][N];
    int a[N][N];
    int head[N],to[N*N],Next[N*N],w[N*N],t;
    inline int read(){
        int ss(0),pp(1);char bb(getchar());
        for(;bb<48||bb>57;bb=getchar())if(bb=='-')pp=-1;
        while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
        return ss*pp;
    }
    inline void add(int x,int y,int z){
        to[++t]=y,w[t]=z;
        Next[t]=head[x],head[x]=t;
        return ;
    }
    inline void _min(int &x,int y){
        x<y?x:(x=y);
        return ;
    }
    signed main(){
        n=read(),m=read();
        memset(dis,0x3f,sizeof(dis));
        memset(f,0x3f,sizeof(f));
        memset(a,0x3f,sizeof(a));
        while(m--){
            int ff=read(),tt=read(),ww=read();
            if(ww<a[ff][tt])a[ff][tt]=ww;
        }
        for(register int i=1;i<=n;++i)
            for(register int j=1;j<=n;++j)
                if(a[i][j]!=lar)add(i,j,a[i][j]);
        for(register int i=1;i<=n;++i)dis[0][i][i]=0;
        for(register int s=1;s<=150;++s)
            for(register int i=1;i<=n;++i)
                for(register int j=1;j<=n;++j)
                    for(register int k=head[j],now=dis[s-1][i][j];k;k=Next[k])
                        _min(dis[s][i][to[k]],now+w[k]);
        for(register int i=1;i<=n;++i)
            for(register int j=1;j<=n;++j)
                f[0][i][i]=0,f[1][i][j]=dis[100][i][j];
        for(register int s=2;s<=100;++s)
            for(register int i=1;i<=n;++i)
                for(register int j=1;j<=n;++j)
                    for(register int k=head[j],now=f[s-1][i][j];k;k=Next[k])
                        _min(f[s][i][to[k]],now+dis[100][j][to[k]]);
        for(register int s=150;~s;--s)
            for(register int i=1;i<=n;++i)
                for(register int j=1;j<=n;++j)
                    _min(dis[s][i][j],dis[s+1][i][j]);
        m=read();
        while(m--){
            int x=read(),y=read(),z=read(),ans=lar;
            for(register int i=1;i<=n;++i)
                _min(ans,f[z/100][x][i]+dis[z%100][i][y]);
            printf("%lld
    ",ans>=lar?-1ll:ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Unbutu之web环境部署——常用软件安装
    利用百度uaredirect.js判断手机终端并自动跳转
    原生Ajax附件上传简单实例
    shader glsl 函数图举例
    pixijs释放纹理的方法
    pixijs shader透明度设置方法
    pixijs 用canvas的方法
    threejs 解决模型缩小有黑边的解决方案
    threejs 透明模型遮挡后面模型解决方案
    javascript canvas 清除图片空白多余的方法
  • 原文地址:https://www.cnblogs.com/remarkable/p/11729192.html
Copyright © 2011-2022 走看看