首页 > 代码库 > qbxt十一系列四

qbxt十一系列四

关于考试:题目很难,T1和T3都失误,爆零orz

技术分享

技术分享

更正:第三组:不存在相同的字符|str|=26,26<=n<=100

【题目分析】

第一反应,组合数学;第二反应,有端倪;jn给了一道题GT考试 很多大神都做过,kmp+矩阵乘法

#include<cstdio>#include<cstring>#include<algorithm>#define ll long longusing namespace std;const int N=1e5+7;const int mod=1e9+7;int n,cnt,len;char str[N],pat[N];ll f[N];void dfs(int now){    if(now==n){        if(++cnt>=mod) cnt%=mod;        return ;    }    bool flag=(now<len-1)|(!equal(str+now-len+1,str+now,pat));    for(char x=a;x<=z;x++){        if(!flag&&x==pat[len-1]) continue;        str[now]=x;        dfs(now+1);    }}ll fpow(ll a,ll p){    ll res=1;    for(;p;p>>=1,a=a*a%mod) if(p&1) res=res*a%mod;    return res;}int main(){    freopen("helloworld.in","r",stdin);    freopen("helloworld.out","w",stdout);    while(scanf("%d",&n)==1){        scanf("%s",pat);        len=strlen(pat);        cnt=0;        if(!n){puts("0");continue;}         if(n<=5){            dfs(0);            printf("%d\n",cnt);        }        else if(len==1){            printf("%d\n",fpow(25,n));        }        else{            f[0]=1;            for(int i=1;i<=len;i++) f[i]=f[i-1]*26%mod;            for(int i=len;i<=n;i++) f[i]=(f[i-1]*26-f[i-len]+mod)%mod;            printf("%d\n",(int)f[n]);        }    }    return 0;}

技术分享

更正:输出的顺序保证a<b

技术分享

更正:输出样例:0 1000000006

【题目分析】

    矩阵乘法斐波那契数列变形

#include<cstdio>#include<cstring>#include<iostream>#ifdef unix#define LL "%lld"#else#define LL "%I64d"#endifusing namespace std;#define ll long long#define N 3const ll mod=1e9+7;ll a[N][N],b[N][N],c[N][N];ll p,q,a1,a2,n;inline const ll read(){    register ll x=0,f=1;    register char ch=getchar();    while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}    return x*f;}void work(){    a[1][1]=0;a[1][2]=q;a[2][1]=1;a[2][2]=p;    b[1][1]=0;b[1][2]=q;b[2][1]=1;b[2][2]=p;    while(n){        if(n&1){            for(int i=1;i<=2;i++){                for(int j=1;j<=2;j++){                    for(int k=1;k<=2;k++){                        c[i][j]=(c[i][j]+a[i][k]*b[k][j]%mod)%mod;                    }                }            }            memcpy(a,c,sizeof c);            memset(c,0,sizeof c);        }        for(int i=1;i<=2;i++){            for(int j=1;j<=2;j++){                for(int k=1;k<=2;k++){                    c[i][j]=(c[i][j]+b[i][k]*b[k][j]%mod)%mod;                }            }        }        memcpy(b,c,sizeof c);        memset(c,0,sizeof c);        n>>=1;    }}int main(){    freopen("gcd.in","r",stdin);    freopen("gcd.out","w",stdout);    p=1;q=1;a1=1;a2=2;    n=read();ll bf=n;    if(n==1){printf("1 1");return 0;}    if(n%mod==0){printf("1 ");printf(LL,n-1);return 0;}    n-=1;    work();    ll ans1=(a[1][1]%mod+a[2][1]%mod)%mod;    n=bf;    work();    ll ans2=(a[1][1]%mod+a[2][1]%mod)%mod;    if(ans1>ans2) swap(ans1,ans2);    printf(LL,ans1);putchar( );printf(LL,ans2);    return 0;}

 

技术分享

更正:模数1000000007

技术分享

【题目分析】

    开始打了匈牙利算法,自我感觉p==1的情况还是可以混过去的吧,结果爆零啦

    考完据shenben和ylf说并不是匈牙利算法!!是树形DP!

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#define maxn 100010#define mod 1000000007#define ll long longusing namespace std;ll T,P,n,head[maxn],num,f[maxn][2],g[maxn][2],L,R[maxn],l,r[maxn],son[maxn];struct node{    ll v,pre;}e[maxn*2];ll init(){    ll x=0,f=1;char s=getchar();    while(s<0||s>9){if(s==0)f=-1;s=getchar();}    while(s>=0&&s<=9){x=x*10+s-0;s=getchar();}    return x*f;}void Add(ll from,ll to){    num++;e[num].v=to;    e[num].pre=head[from];    head[from]=num;}void Clear(){    num=0;    memset(f,0,sizeof(f));    memset(g,0,sizeof(g));    memset(head,0,sizeof(head));}void DP(ll now,ll from){    g[now][0]=1;    ll mx,sum;    for(int i=head[now];i;i=e[i].pre){        ll v=e[i].v;        if(v==from)continue;        DP(v,now);//x不连儿子 儿子们可连可不连         mx=max(f[v][1],f[v][0]);sum=0;        if(mx==f[v][1])sum+=g[v][1];        if(mx==f[v][0])sum+=g[v][0];        g[now][0]=g[now][0]*sum%mod;        f[now][0]+=mx;    }    //x连某个儿子 这个不选 其他的连或者不连     L=0;l=1;ll S=0;    for(int i=head[now];i;i=e[i].pre)         if(e[i].v!=from)son[++S]=e[i].v;    R[S+1]=0;r[S+1]=1;    for(int i=S;i>=1;i--){        ll v=son[i];sum=0;        mx=max(f[v][1],f[v][0]);        if(mx==f[v][1])sum+=g[v][1];        if(mx==f[v][0])sum+=g[v][0];        R[i]=R[i+1]+mx;        r[i]=r[i+1]*sum%mod;    }    for(int i=1;i<=S;i++){        ll v=son[i];        mx=L+f[v][0]+R[i+1]+1;        if(mx>f[now][1]){            f[now][1]=mx;            g[now][1]=l*g[v][0]%mod*r[i+1]%mod;        }        else if(mx==f[now][1])            g[now][1]=(g[now][1]+l*g[v][0]%mod*r[i+1]%mod)%mod;        sum=0;        mx=max(f[v][1],f[v][0]);        if(mx==f[v][1])sum+=g[v][1];        if(mx==f[v][0])sum+=g[v][0];        l=l*sum%mod;L+=mx;    }}int main(){    freopen("hungary.in","r",stdin);    freopen("hungary.out","w",stdout);    T=init();P=init();    while(T--){        n=init();        ll u,v;Clear();        for(int i=1;i<n;i++){            u=init();v=init();            Add(u,v);Add(v,u);        }        DP(1,0);ll sum,mx;        mx=max(f[1][0],f[1][1]);sum=0;        if(mx==f[1][0])sum+=g[1][0],sum%=mod;        if(mx==f[1][1])sum+=g[1][1],sum%=mod;        if(P==1)cout<<mx<<endl;        if(P==2)cout<<mx<<" "<<sum<<endl;    }    return 0;}

 

技术分享

技术分享

 【题目分析】

    不会

#include<cstdio>using namespace std;const int N=205;const int inf=0x3f3f3f3f;inline int max(int a,int b){return a>b?a:b;} inline const int read(){    register int x=0,f=1;    register char ch=getchar();    while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}    return x*f;}int n,m;int f[N][N];int main(){    freopen("radius.in","r",stdin);    freopen("radius.out","w",stdout);    n=read();m=read();    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=inf;    for(int i=1,x,y,z;i<=m;i++){        x=read();y=read();z=read();        if(f[x][y]>z) f[y][x]=f[x][y]=z;    }    for(int k=1;k<=n;k++){        for(int i=1;i<=n;i++){            for(int j=1;j<=n;j++){                if(i!=j&&j!=k&&i!=k){                    if(f[i][j]>f[i][k]+f[k][j]){                        f[i][j]=f[i][k]+f[k][j];                    }                }            }        }    }    int d=0;    for(int i=1;i<n;i++){        for(int j=i+1;j<=n;j++){            if(f[i][j]!=inf) d=max(d,f[i][j]);        }    }    double ans=d/2.0;    printf("%.2lf",ans);    return 0;}

 

qbxt十一系列四