HDU6129(杨辉三角和万恶的Lucas)

来源:互联网 发布:西瑞鞋子怎么样知乎 编辑:程序博客网 时间:2024/06/05 03:16

菜死了,比赛的时候T到哭
表格中ai代表i个a异或

m a1 a2 a3 a4 1 a1 a1^a2 a1^a2^a3 a1^a2^a3^a4 2 a1 a21^a2 a31^a22^a3 a41^a32^a23^a4 3 a1 a31^a2 a61^a32^a3 a101^a62^a33^a4 4 a1 a41^a2 a101^a42^a3 a201^a102^a43^a4



很简单就可以找出其中系数的规律,对于异或而言,异或相同的数偶数次相当于没有异或,那么我们只需要找出其中奇数就可以了.
注意了万恶的Lucas定理:Cmn是奇数当且仅当把a,b二进制表达后b中1的位置是a中1的位置的子集
比赛的时候根本不知道,用Lucas求组合数,T到哭.
TLE code:

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<string>//a&3==a%4using namespace std;#define ll long long#define mem(a) memset(a,0,sizeof(a))const double eps=1e-8;const int maxn=200010;//须填写const int inf=0x3f3f3f3f;const int p=1e9+7;int a[maxn+10];int b[maxn+10];long long Pow(long long a,long long b){    long long ans=1;    while(b)    {        if(b&1)        {            b--;            ans=(ans*a)%p;        }        b>>=1;        a=(a*a)%p;    }    return ans;}long long C(long long n,long long m){    if(n<m)        return 0;    long long a=1,b=1;    while(m)    {        a=(a*n)%p;        b=(b*m)%p;        m--;        n--;    }    return (a*Pow(b,p-2))%p;}long long Lucas(long long n,long long m){    if(m==0)        return 1;    return Lucas(n/p,m/p)*C(n%p,m%p)%p;}bool C(int n,int b){    ll x=(ll)n;    ll y=(ll)b;    ll ans=Lucas(x,y);    if(ans%2==1)        return true;    else return false;}int main(){    int kase;    scanf("%d",&kase);    while(kase--)    {        mem(a);        mem(b);        int n,m;        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)        {            scanf("%d",a+i);        }        for(int i=1;i<=n;i++)        {            for(int j=i;j>0;j--)            {                if(C(m-1+i-j,m-1))                {                    b[i]=b[i]^a[j];                }            }        }        for(int i=1;i<n;i++)        {            printf("%d ",b[i]);        }        printf("%d\n",b[n]);    }    return 0;}

AC code:

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<string>//a&3==a%4using namespace std;#define ll long long#define mem(a) memset(a,0,sizeof(a))const double eps=1e-8;const int maxn=200010;//须填写const int inf=0x3f3f3f3f;const int mod=1e9+7;int a[maxn];int b[maxn];int main(){    int kase;    scanf("%d",&kase);    while(kase--)    {        mem(a);        mem(b);        int n,m;        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)        {            scanf("%d",a+i);        }        for(int i=1;i<=n;i++)        {            int x=i+m-2;            int y=i-1;            if((x&y)==y)//y的1位置是x的子集则(x&y)==y            {                for(int j=i;j<=n;j++)                    b[j]^=a[j-i+1];            }        }        for(int i=1;i<n;i++)        {            printf("%d ",b[i]);        }        printf("%d\n",b[n]);    }    return 0;}
原创粉丝点击