关于考试:题目很难,T1和T3都失误,爆零orz
更正:第三组:不存在相同的字符|str|=26,26<=n<=100
【题目分析】
第一反应,组合数学;第二反应,有端倪;jn给了一道题GT考试 很多大神都做过,kmp+矩阵乘法
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using 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" #endif using namespace std; #define ll long long #define N 3 const 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 long using 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; }
时间: 2024-10-08 20:50:25