Bestcoder round#85 解题报告

来源:互联网 发布:张大奕淘宝店有几家 编辑:程序博客网 时间:2024/05/18 02:40

1001 sum

计算下前缀和,看有没有模m相同的即可。

#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<stack>#include<vector>#include<bitset>using namespace std;int pp[5100];int T;int flag;int n,k;int sum;int main(){    scanf("%d",&T);    while (T--)    {        flag=0;        memset(pp,0,sizeof(pp));        pp[0]=1;        scanf("%d %d",&n,&k);        sum=0;        for (int i=1;i<=n;i++)        {            int x;            scanf("%d",&x);            sum=(sum+x)%k;            if (pp[sum]) flag=1;            pp[sum]=1;        }        if (flag) printf("YES\n");        else printf("NO\n");    }    return 0;}

1002 domino

贪心去掉k1个最大值即可

#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<stack>#include<vector>#include<bitset>using namespace std;typedef long long LL;int a[110000];int T;int flag;int n,k;LL ans;int main(){    scanf("%d",&T);    while (T--)    {        scanf("%d %d",&n,&k);        for (int i=1;i<n;i++)            scanf("%d",&a[i]);        sort(a+1,a+n);        ans=0;        for (int i=1;i<=max(n-k,0);i++)            ans+=(LL)(a[i]+1LL);        cout<<ans+min((LL)k,(LL)n)<<endl;    }    return 0;}

1003 abs

因为y的每个质因子的次数都为2,所以y为完全平方数,然后暴力枚举下d(y=dd),判断d是否每个质因子都只出现了一次。

#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<stack>#include<vector>#include<bitset>#include<ctime>using namespace std;typedef long long LL;LL x;int T;LL ans1,ans2;int check(LL x){    for (LL i=2;i*i<=x;i++)    {        if (x%i==0)        {            x/=i;            if (x%i==0) return 0;        }    }    return 1;}int main(){    cin>>T;    while (T--)    {           cin>>x;        LL d=(LL)sqrt((double)x+0.5);        for (LL i=1;;i++)        {            if (check(d+i)&&d+i>=2)            {                ans1=abs(x-(d+i)*(d+i));                break;            }        }        ans2=1e18;         for (LL i=0;;i++)        {            if ((d-i)<2) break;            if (check(d-i))            {                ans2=abs(x-(d-i)*(d-i));                break;            }        }        cout<<min(ans1,ans2)<<endl;    }    return 0;}

1004 Tower Defence

dp,f[i][j][k]i表示1号点所在的联通块的大小,j表示1号点与联通块内其他点的最大距离,k表示与1号点最短距离恰好为j的点的个数,f[i][j][k]表示这样的方案数。考虑其对答案的贡献,对于不在1号点所在联通块内的 其他点,可以随便连,方案数为2n(n1)2,将其乘起来即可。下面考虑f[i][j][k]的转移。枚举距离为j+1的点的个数l,首先用组合数从剩余n-i个点中选出l个点,这些点一定与第j层的点连至少一条边,所以层与层之间的连接方案为2k1,其次,这些点之间也可以互相连边,方案数为2l(l1)2。那么其对f[i+l][j+1][l]的贡献应该为

f[i][j][k]Clni(2k1)(2l(l1)2)

#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<stack>#include<vector>#include<bitset>#include<ctime>using namespace std;typedef long long LL;const LL mod=1e9+7;int n,k;LL f[61][61][61];LL ans;LL pow_mod(LL a,LL b,LL p){    LL tmp=1;    a%=p;    for(LL i=b;i;i>>=1,a=a*a%p)        if(i&1)tmp=tmp*a%p;    return tmp;}int T;LL C[70][70];int main(){    C[0][0]=1;    for(int i=1;i<=61;i++){        C[i][0]=1;        for (int j=1;j<=i;j++)            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;    }    scanf("%d",&T);    while (T--)    {           scanf("%d %d",&n,&k);        memset(f,0,sizeof(f));        f[1][0][1]=1;        ans=0;        for (int i=0;i<k;i++)        {            for (int j=1;j<=n;j++)                for (int l=1;l<=j;l++)                {                    if (f[j][i][l]==0) continue;                    ans=(ans+f[j][i][l]*pow_mod(2,(LL)(n-j)*(n-j-1)/2LL,mod))%mod;                    for (int ll=1;ll<=n-j;ll++)                    {                        LL d=(((f[j][i][l]*pow_mod(pow_mod(2,l,mod)-1+mod,ll,mod))%mod)*pow_mod(2,(LL)(ll)*(ll-1)/2LL,mod))%mod;                        d=(d*C[n-j][ll])%mod;                        f[j+ll][i+1][ll]=(f[j+ll][i+1][ll]+d)%mod;                    }                }        }        cout<<ans<<endl;    }    return 0;}

1005 gcd

首先证明一个小结论:
x1时,不妨设a>b:

(xa1)1(modx)

gcd(xa1,xab)=1

gcd(xa1,xb1)=gcd(xa1,xaxab)=gcd(xab1,xa1)

由此可以得出:
gcd(xa1,xb1)=xgcd(a,b)1

gcd(xa1,xb1)=xgcd(a,b)1

枚举d=gcd(a,b),设其出现次数为s[d],易得
s[d]=2(ϕ(1)+ϕ(2)++ϕ(nd))1

我们发现s[d]的值只与nd的有关,且这个值在1n上有n段,我们可以枚举并二分出区间,对于每个区间l,r,对答案的贡献为
s[nl]i=lr(xi1)

s数组的值可以预处理出来,后面那部分可以利用等比数列公式和乘法逆元求得,总的时间复杂度为O(n+Tnlogn)

#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<stack>#include<vector>#include<bitset>using namespace std;typedef long long LL;int T;const int maxn=1100000;const LL mod=1e9+7;LL phi[maxn];LL sum[maxn];LL ans;LL x,n;LL l,r;void getPhi(){    for (int i=1;i<maxn;i++)        phi[i]=i;    for (LL i=2;i<maxn;i++)        if (i==phi[i])            for (LL j=i;j<maxn;j+=i)                phi[j]=(phi[j]/i)*(i-1);}LL cal(LL x){    LL l=1,r=n,ans;    while (l<=r)    {        LL mid=l+r>>1;        if (n/mid>=x) ans=mid,l=mid+1;        else r=mid-1;    }    return ans;}LL extended_gcd(LL a,LL b,LL &x,LL &y){    if (b==0)    {        x=1,y=0;        return a;    }    else    {        LL r=extended_gcd(b,a%b,y,x);        y-=x*(a/b);        return r;    }}LL pow_mod(LL a,LL b,LL p){    LL tmp=1;    a%=p;    for(LL i=b;i;i>>=1,a=a*a%p)        if(i&1)tmp=tmp*a%p;    return tmp;}LL inv(LL a,LL n){    LL xx,yy,d=extended_gcd(a,n,xx,yy);    return (xx%n+n)%n;}LL cc(LL l,LL r){    LL res=(pow_mod(x,r+1,mod)-pow_mod(x,l,mod)+mod)*(inv(x-1,mod))%mod;    res=(res-r+l-1+mod)%mod;    return res;}int main(){    getPhi();    for (int i=1;i<maxn;i++)        sum[i]=(sum[i-1]+phi[i])%mod;    for (int i=1;i<maxn;i++)        sum[i]=(2*sum[i]-1)%mod;    cin>>T;    while (T--)    {        cin>>x>>n;        if (x==1)        {            cout<<0<<endl;            continue;        }        ans=0;        l=1;        while (l<=n)        {            r=cal(n/l);            ans=(ans+cc(l,r)*sum[n/l])%mod;            l=r+1;        }        cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击