BZOJ4402: Claris的剑

根据那个本质不同我们可以搞出一个构造方法使得该方法构造不重复且搞好是所求的

我们设最大的数为T
那么需要有(n-T)的多余
那么就是相当于 (n-T)>>1 放入T个盒子中注意空盒也可以

那么就有贡献为C(⌊t2 ⌋+T,T)
这里有一个关于求阶乘逆元的小技巧
先求出 N! 的逆元 那么 (N1)! 的逆元就可以O(1)算了

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const
   int Mod=1000000007;
int fact[2000001],fact_[20000001];
inline int Cal(int x,int y)
{
   if(x<0)return 0;
   x>>=1;
   if(x==0)return 1;
   return fact[x+y]*1ll*fact_[x]%Mod*fact_[y]%Mod;
}
int Max=2000000;

int f(int x,int y)
{
   if(y==1)return x;
   int t=f(x,y>>1);
   if(y&1)return t*1ll*t%Mod*1ll*x%Mod;
   else return t*1ll*t%Mod;
}

int ff(int x,int y)
{
    int base=1,res=1,M=x;
    while(y)
    {
       if(y&base)
           y^=base,res=res*1ll*M%Mod;
        base<<=1;
        M=M*1ll*M%Mod;
    }
return res;
}

char c;
inline void read(int &a)
{
  a=0;do c=getchar();while(c<'0'||c>'9');
  while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}

int main()
{
    int i,j,k;
    int n,m;
    read(n),read(m); 
    fact[1]=1;
    Max=min(Max,max(n,m)+4);
    for(i=2;i<=Max;i++)
    fact[i]=fact[i-1]*1ll*i%Mod;
   fact_[Max]=ff(fact[Max],Mod-2);
    for(int i=Max-1;i;i--)
     fact_[i]=fact_[i+1]*(i+1ll)%Mod;
    int ans=0;
     if(n&&m)ans=1; 
  for(i=2;i<=m;i++){(ans+=Cal(n-i,i-1))%=Mod;(ans+=Cal(n-i-1,i-1))%=Mod; } 
  printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(BZOJ4402: Claris的剑)