解题思路
规律如上,乘号前面的是系数,后面的是系列的下标,可以发现系数与杨辉三角有关
然后就上个组合数就好了。
PS:比赛的时候处理组合数部分用了Lucas定理,其实不用的,直接暴力求就好了。(要用逆元)
代码
《懒得手推结果打规律打了1h》
打规律的code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
int n,T,v[100010];
string a[100010][2];
int main() {
cin>>T;
while(T--) {
scanf("%d",&n);
memset(v,0,sizeof(v));
for(int i=1; i<=n; i++) {
a[i][1]=i+48;
a[i][1]="+"+a[i][1];
}
bool ok=1;
for(int i=n; i>1; i--) {
for(int j=1; j<i; j++) {
if(i%2==0)
a[j][ok^1]=a[j][ok]+a[j+1][ok];
else {
int l=a[j+1][ok].size();
a[j][ok^1]=a[j][ok];
for(int t=0; t<l; t+=2) {
if(a[j+1][ok][t]=='-')
a[j][ok^1]=a[j][ok^1]+"+"+a[j+1][ok][t+1];
else a[j][ok^1]=a[j][ok^1]+"-"+a[j+1][ok][t+1];
//cout<<a[j][ok^1]<<endl;
}
}
}
ok=ok^1;
}
// if(a[1][ok][0]!='-')a[1][ok]="+"+a[1][ok];
a[1][ok]=" "+a[1][ok];
int len=a[1][ok].size();
for(int i=1; i<=n; i++) {
int x=0,y=0;
for(int j=1; j<len; j++) {
if(a[1][ok][j]=='+'&&a[1][ok][j+1]==i+48)
x++;
if(a[1][ok][j]=='-'&&a[1][ok][j+1]==i+48)
y++;
}
v[i]=x-y;
}
for(int i=1; i<=n; i++) {
if(v[i])
cout<<v[i]<<"*"<<i<<" ";
}
}
}
考场代码,太丑了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
map<ll,ll>fac;
const int mod=1e9+7;
int n;
ll a[100010],c[100010],ans;
ll ksm(ll a,ll x)
{
ll ans=1,base=a%mod;
while(x)
{
if(x&1)ans=ans*base%mod;
base=base*base%mod;
x=x>>1;
}
return ans;
}
ll C(ll n,ll m)
{
if(n<m)return 0;
return (fac[n]*ksm(fac[m],mod-2))%mod*ksm(fac[n-m],mod-2)%mod;
}
ll lucas(ll n,ll m){
if(m==0)
return 1;
return C(n%mod,m%mod)*lucas(n/mod,m/mod)%mod;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
if(n==1){
printf("%lld",(a[1]+mod)%mod);
return 0;
}
if(n==2){
printf("%lld",(a[1]+a[2]+mod)%mod);
return 0;
}
if(n==3){
printf("%lld",(a[1]-a[3]+mod)%mod);
return 0;
}
if(n==4){
printf("%lld",(a[1]+a[2]-a[3]-a[4]+mod)%mod);
return 0;
}
fac[0]=fac[1]=1;
for(int i=2;i<=100;i++)
fac[i]=fac[i-1]*i%mod;
if(n>4)
{
int nn=(n-1)/2;
ll ok=1,cnt=0;
if(n%2!=0)
{
for(int i=1;i<=n+1;i+=2)
{
ll CC=lucas(nn,cnt);
ans=(ans+(ok*CC+mod)%mod*a[i]%mod)%mod;
cnt++;
ok=-ok;
}
}
else
{
for(int i=1;i<=n;i+=2)
{
ll CC=lucas(nn,cnt);
ans=(ans+(ok*CC+mod)%mod*a[i]%mod)%mod;
ans=(ans+(ok*CC+mod)%mod*a[i+1]%mod)%mod;
cnt++;
ok=-ok;
}
}
}
printf("%lld",ans);
}