分析可知,要满足至少存在一个gcd为偶数的情况,则需要至少一个偶数位上是偶数(位数和数据均为偶数才会使得gcd为偶数)
则可以采取逆向思维,求出偶数全不在偶数位的情况数a、所有排列数b;
结果则为b-a;
依据排列组合知识可知,所有排列数b=n!(n的阶乘)
当偶数个数等于奇数个数时,偶数个数和奇数个数均为n/2;a=(n/2)!*(n/2)!
当偶数个数小于奇数个数时,奇数个数为n/2+1,偶数个数为n/2;a=(n/2+1)*(n/2)!*(n/2+1)!=(n/2+1)!*(n/2+1)!
如果结果b-a出现负数,加上mod
注意:当偶数个数小于奇数个数时,请不要写a=(n/2+1)*(n/2)!*(n/2+1)!,因为(n/2+1)*(n/2)!可能过大,但是没有取模。
应该改写成a=(n/2+1)!*(n/2+1)!或a=(n/2+1)*(n/2)!%mod*(n/2+1)
#include<stdio.h> #include<math.h> long long mod = 1e9+7; long long jiechen(long long n){ long long ans=1; for(long long i=n;i>0;i--){ ans=ans*i%mod; } return ans; } int main(){ long long n; scanf("%lld",&n); long long sum=jiechen(n),oushu=n/2,jishu=n-oushu; long long wrong; if(jishu>oushu){ wrong=jiechen(jishu)*jiechen(jishu); }else{ wrong=jiechen(oushu)*jiechen(jishu); } if(oushu==0){ printf("0"); }else{ long long ans=(sum-wrong)%mod; if(ans<0){ ans+=mod; } printf("%lld",ans); } return 0; }