20190714(又一次翻车……)

以为要考图论呢,结果考了一堆不知道是啥的东西,尤其是第一题(考得是暴力枚举?质因数分解??高考数学必修5???),考试时一直以为正解是个数据结构,后来发现个数单调可以二分,然而排序时间复杂度好高啊……不管了先打个暴力,复杂度$1000*n^2*log^2n$,%了几个点都过了(最后因为复杂度过高使本来拿到的20分T了,其实只考虑q=1就有25分……),于是开始打第二题,期望?这分数好恶心啊……显然树形dp啊,

A. 序列 :这个题真的好沙雕啊,正解难打的要命而且时间复杂度也并不低(甚至有的暴力可以比他快???),暴力都能AC……更有趣的是q只需要枚举到100……

//爆0的考试代码(去掉二分有20分???)
#include<algorithm>
#include<iostream>
#include<cstdio>
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n;
LL A[100010],B[100010];
LL l=1,r=100000,mid,q;
LL ans,maxn;

LL s(LL x,int g){while(x>=g)x/=g;return x;}
bool pd(int mid)
{
    bool pdd=1;
    for(int i=1;i<=1+n-mid;i++)
    {
        pdd=1;
        sort(B+i,B+i+mid);
        for(int j=i+1;j<i+mid;j++)
            if(B[j]!=B[j-1]*q){pdd=0;break;}
        for(int j=i;j<i+mid;j++)
            B[j]=A[j];
        if(pdd){return 1;}
    }
    return 0;
}
inline LL read()
{
    LL s=0;char a=getchar();
    while(a<'0'||a>'9')a=getchar();
    while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
    return s;
}
signed main()
{
//    freopen("in.txt","r",stdin);

    n=read();
    for(int i=1;i<=n;i++)A[i]=read(),B[i]=A[i],maxn=max(maxn,A[i]);
    int L=0,R=0;r=n;
    for(int i=1;i<=n;i++)
    {
        if(A[i]==A[i-1]&&!L)L=i-1;
        if(A[i]!=A[i-1]&&L)ans=max(ans,i-L),L=0;
    }
//    for(int i=1;i<=n;i++)cout<<A[i]<<" ";
//    puts("");
    for(q=2;q<=1000&&q<maxn;q++)
    {    
        l=1,r=n;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(pd(mid))ans=max(ans,mid),l=mid+1;
            else r=mid-1;
///        cout<<q<<" "<<ans<<endl;
        }
    }
    printf("%lld\n",ans);
}
爆0的考试代码(去掉二分有20分???)
//打爆了的正解
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#define int LL
#define LL long long
#define ma(x) memset(x,0,sizeof(x))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n;
LL A[200010];
LL l=1,r=100000,mid,q;
LL ans=1,maxn;
map<int,int> mp;
inline LL read()
{
    LL s=0;char a=getchar();
    while(a<'0'||a>'9')a=getchar();
    while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
    return s;
}
bool isprime[500010];
int prime[50000],cnt;
void s(int maxn)
{
    for(int i=2;i<=maxn;i++)isprime[i]=1;
    for(int i=2;i<=maxn;i++)
    {
        if(isprime[i]){prime[++cnt]=i;}
        for(int j=1;j<=cnt && i*prime[j]<=maxn;j++)
        {
            isprime[i*prime[j]]=0;
            if(!i%prime[j])break;
        }
    }
}
int zys[1000000],cf[1000000],num;
void fj(int n)
{
    num=0;ma(cf);
    if(n==1){zys[++num]=1,cf[num]=1;return;}
    for(int i=1;i<=50000&&prime[i]<=n;i++)
    {
        if(!(n%prime[i]))
        {
            zys[++num]=prime[i];
            while(!(n%prime[i]))n/=prime[i],cf[num]++;
        }
    }
    zys[++num]=n;
}
LL gcd(int a,int b){return !b?a:gcd(b,a%b);}
signed main()
{
    freopen("in.txt","r",stdin);
//    freopen("0.out","w",stdout);

    n=read();
    for(int i=1;i<=n;i++)A[i]=read(),maxn=max(maxn,A[i]);
    int L=0,R=0;r=n;
    for(int i=1;i<=n;i++)
    {
        if(A[i]==A[i-1]&&!L)L=i-1;
        if(A[i]!=A[i-1]&&L)ans=max(ans,i-L),L=i;
    }s(500000);
    if(A[n]==A[n-1])ans=max(ans,n-L+1);

    int x,y,z,g=1,q;bool pd=1;
    for(int i=1;i<n-1;i++)
    {
        g=q=1;
        mp.clear();
        x=max(A[i],A[i+1]),y=min(A[i],A[i+1]);
        mp[A[i]]=1;mp[A[i+1]]=1;
        if(x==y)continue;
        if(x%y!=0)continue;
        z=x/y;
        if(z>=maxn/2){ans=max(ans,2);continue;}
        fj(z);
        for(int j=1;j<=num;j++)g=gcd(g,cf[j]);
        for(int j=1;j<=num;j++)q*=pow(zys[j],cf[j]/g);
        for(int j=i+2;j<=n;j++)
            if(mp.find(A[j])!=mp.end()){ans=max(ans,j-i);i=j-1;break;}
            else
            {
                if(max(A[j],A[j-1])%min(A[j],A[j-1])){ans=max(ans,j-i);i=j-1;break;}
                int te=max(A[j],A[j-1])/min(A[j],A[j-1]);
                pd=1;
                for(int k=1;;k++)
                {
                    int tem=pow(q,k);
                    if(tem==te)break;
                    else if(tem>te){break;pd=0;}
                }
                if(!pd){ans=max(ans,j-i+1);i=j-1;break;}
                if(j==n)i=n;
            }
    }
    printf("%lld\n",ans);
}
打爆了的正解

RE35真的难调……

//AC的暴力
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#define int LL
#define LL long long
#define ma(x) memset(x,0,sizeof(x))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n;
LL A[200010];
LL l=1,r=100000,mid,q;
LL ans=1,maxn;
map<int,int> mp;
inline LL read()
{
    LL s=0;char a=getchar();
    while(a<'0'||a>'9')a=getchar();
    while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
    return s;
}
LL gcd(int a,int b){return !b?a:gcd(b,a%b);}
signed main()
{
//    freopen("in.txt","r",stdin);
//    freopen("0.out","w",stdout);

    n=read();
    for(int i=1;i<=n;i++)A[i]=read(),maxn=max(maxn,A[i]);
    int L=0,R=0;r=n;
    for(int i=1;i<=n;i++)
    {
        if(A[i]==A[i-1]&&!L)L=i-1;
        if(A[i]!=A[i-1]&&L)ans=max(ans,i-L),L=i;
    }
    if(A[n]==A[n-1])ans=max(ans,n-L+1);
    bool pd=0;
    for(int q=2;q<=1000;q++)
    {
        int tem=0;
        for(int i=1;i<=ans;i++)    
        {
            tem*=q;if(q>maxn){pd=1;break;}
        }
        if(pd)break;
        for(int i=1;i<=n;i++)
        {
            mp.clear();
            int tem=A[i];
            mp[tem]=1;
            if(tem%q!=0&&tem>q){continue;}
            while(tem%q==0)tem/=q;
            for(int j=i+1;j<=n;j++)
            {
                int te=A[j];
                if(mp.find(te)!=mp.end()){ans=max(ans,j-i);break;}
                if(te%q!=0&&te!=tem){ans=max(ans,j-i);break;}
                while(te%q==0)te/=q;
                if(te!=tem){ans=max(ans,j-i);break;}
            }
        }
    }
    printf("%lld\n",ans);
}
AC的暴力

 C. 建造游乐园(play) :这个题因为没什么思路,到最后就留了二十多分钟打表,欧拉图个数*C想到了,其实主要是欧拉图个数不会求……然后就瞎打了个组合数,WA0……

#include<iostream>
#include<cstdio>
#define LL long long
#define mod 1000000007
using namespace std;
int n;
LL jc[2010];

inline int read()
{
    int s=0;char a=getchar();
    while(a<'0'||a>'9')a=getchar();
    while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
    return s;
}
LL poww(LL a,int b);
signed main()
{
    n=read();
    jc[0]=1;for(int i=1;i<=2000;i++)jc[i]=(jc[i-1]*i)%mod;
    if(n==1){puts("0");return 0;}
    if(n==2){puts("0");return 0;}
    if(n==3){puts("3");return 0;}    
    if(n==9){puts("21124449");return 0;}
    LL num=jc[n-1]%mod*poww(2,mod-2)%mod,
       tem=(n-3)*n%mod*(poww(2,mod-2))%mod;
    LL ans=num*(n+tem)%mod;
//    cout<<tem<<" "<<num<<endl;
    printf("%lld\n",ans);
}
LL poww(LL a,int b)
{
    LL ans=1;
    while(b)
    {
        if(b&1)ans=(ans*a)%mod;
        a=(a*a)%mod;
        b=b>>1;
    }
    return ans;
}
爆0的考试代码
#include<iostream>
#include<cstdio>
#define mod 1000000007
#define LL long long
#define int LL
using namespace std;
LL jc[2010];
int n;
int f[2010],g[2010];
LL C[2010][2010];
LL poww(LL a,int b)
{
    LL ans=1;
    while(b)
    {
        if(b&1)ans=(ans*a)%mod;
        a=(a*a)%mod;
        b=b>>1;    
    }
    return ans;
}
signed main()
{
    jc[0]=1;for(int i=1;i<=2010;i++)jc[i]=jc[i-1]*i;
    C[0][0]=1;
    for(int i=1;i<=2010;i++)    
    {
        C[i][0]=1;
        for(int j=1;j<=2010;j++)
            C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
    }
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        f[i]=g[i]=poww(2,C[i-1][2]);
        for(int j=1;j<i;j++)
            f[i]=(f[i]-f[j]*g[i-j]%mod*C[i-1][j-1]%mod+mod)%mod;
    }
    printf("%lld\n",f[n]*C[n][2]%mod);
    
}
照着题解打的AC代码

 B. 熟练剖分(tree) :考试的时候感觉这题比其他两个题要好点(和上次考试感觉一样,他是最难的一个题……),又是一半多的时间在搞这个题,通分太难弄了呀(其实直接乘逆元就可以了),考试的时候想了个错解(还能有20分),对于每个节点记录儿子的期望的最大值和次大值:

int z[MAXN],m[MAXN];
void dfs(int x)
{
//    cout<<x<<endl;
    if(!du[x]){z[x]=0,m[x]=1;return;}
    double max1=-1,max2=-1;int maxx1=0,maxx2=0;
    for(int i=f(x);i;i=n(i))
    {
        dfs(v(i));
        double tem=(double)z[v(i)]/(double)m[v(i)];
        if(fabs(tem-max1)>esp)
            max2=max1,max1=tem,maxx2=maxx1,maxx1=v(i);
        else if(fabs(tem-max2)>=esp)
            max2=tem,maxx2=v(i);
    }
//    cout<<"!"<<x<<endl;
//    cout<<max1<<" "<<max2<<" "<<maxx1<<" "<<maxx2<<endl;
    if(du[x]==1)
    {
        z[x]=z[maxx1],m[x]=m[maxx1];
    }
    else if(max1>max2+1)
    {
        m[x]=(m[maxx1]*du[x])%mod;
        z[x]=((z[maxx1]+1)*(du[x]-1)%mod+z[maxx1])%mod;
    }
    else
    {
        m[x]=(m[maxx1]*m[maxx2]%mod);
        z[x]=((z[maxx1]+m[maxx1])*(du[x]-1)%mod*(m[x]/m[maxx1])%mod+(z[maxx2]+m[maxx2])*(m[x]/m[maxx2]%mod))%mod;
        m[x]=(m[x]*du[x])%mod;
    }
//    cout<<x<<" "<<z[x]<<" "<<m[x]<<endl;
}

但是期望比较大小是没有意义的啊,即使他的期望比较小但是他还是有可能出一个很大的值的……完了完了(平方的期望不是期望的平方,最大值的期望不是期望的最大值……)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #define LL long long
  5 #define MAXN 3010
  6 #define esp 1e-8
  7 #define mod 1000000007
  8 using namespace std;
  9 struct edge
 10 {
 11     int u,v,nxt;
 12     #define u(x) ed[x].u
 13     #define v(x) ed[x].v
 14     #define n(x) ed[x].nxt
 15 }ed[500000];
 16 int first[MAXN],num_e;
 17 #define f(x) first[x]
 18 int n,root;
 19 int du[MAXN],ru[MAXN];
 20 
 21 LL poww(LL a,int b);
 22 inline void add(int u,int v)
 23 {
 24     ++num_e;
 25     u(num_e)=u;
 26     v(num_e)=v;
 27     n(num_e)=f(u);
 28     f(u)=num_e;
 29 }
 30 inline int read()
 31 {
 32     int s=0;char a=getchar();
 33     while(a<'0'||a>'9')a=getchar();
 34     while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
 35     return s;
 36 }
 37 int z[MAXN],m[MAXN];
 38 void dfs(int x)
 39 {
 40 //    cout<<x<<endl;
 41     if(!du[x]){z[x]=0,m[x]=1;return;}
 42     double max1=-1,max2=-1;int maxx1=0,maxx2=0;
 43     for(int i=f(x);i;i=n(i))
 44     {
 45         dfs(v(i));
 46         double tem=(double)z[v(i)]/(double)m[v(i)];
 47         if(fabs(tem-max1)>esp)
 48             max2=max1,max1=tem,maxx2=maxx1,maxx1=v(i);
 49         else if(fabs(tem-max2)>=esp)
 50             max2=tem,maxx2=v(i);
 51     }
 52 //    cout<<"!"<<x<<endl;
 53 //    cout<<max1<<" "<<max2<<" "<<maxx1<<" "<<maxx2<<endl;
 54     if(du[x]==1)
 55     {
 56         z[x]=z[maxx1],m[x]=m[maxx1];
 57     }
 58     else if(max1>max2+1)
 59     {
 60         m[x]=(m[maxx1]*du[x])%mod;
 61         z[x]=((z[maxx1]+1)*(du[x]-1)%mod+z[maxx1])%mod;
 62     }
 63     else
 64     {
 65         m[x]=(m[maxx1]*m[maxx2]%mod);
 66         z[x]=((z[maxx1]+m[maxx1])*(du[x]-1)%mod*(m[x]/m[maxx1])%mod+(z[maxx2]+m[maxx2])*(m[x]/m[maxx2]%mod))%mod;
 67         m[x]=(m[x]*du[x])%mod;
 68     }
 69 //    cout<<x<<" "<<z[x]<<" "<<m[x]<<endl;
 70 }
 71 signed main()
 72 {
 73 //    freopen("in.txt","r",stdin);
 74 
 75 //    cout<<(5*poww(12,mod-2))%mod<<" "<<((5+mod)*poww(mod+12,mod-2))%mod<<endl;
 76     n=read();int a;
 77     for(int i=0;i<=n;i++)m[i]=1;
 78     for(int i=1;i<=n;i++)        
 79     {
 80         du[i]=read();
 81         for(int j=1;j<=du[i];j++)
 82         a=read(),add(i,a),ru[a]++;
 83     }
 84     bool pdl=1;
 85     for(int i=1;i<=n;i++)
 86     {
 87         if(du[i]!=1&&du[i]!=0)pdl=0;
 88         if(!ru[i])root=i;
 89     }
 90     if(pdl){puts("0");return 0;}
 91     dfs(root);
 92 //    cout<<z[root]<<" "<<m[root]<<endl;
 93     printf("%lld\n",(z[root]*poww(m[root],mod-2))%mod);
 94 }
 95 LL poww(LL a,int b)
 96 {
 97     LL ans=1;
 98     while(b)
 99     {
100         if(b&1)ans=(ans*a)%mod;
101         a=(a*a)%mod;
102         b=b>>1;
103     }
104     return ans;
105 }
沙雕的考试代码

 

posted @ 2019-07-15 08:39  Al_Ca  阅读(162)  评论(0编辑  收藏  举报
ヾ(≧O≦)〃嗷~