1. 程式人生 > >20181009noip HZ EZ兩校聯考sum(莫隊,組合數學)

20181009noip HZ EZ兩校聯考sum(莫隊,組合數學)

span lan bubuko 改變 lse print register color names

題面戳這裏

思路:

noip考莫隊???!!!

考場上死活沒往這方面想啊!!!數據分治忘寫endl50pts滾粗了

這裏每個詢問都有n,m兩個參數

我們可以把它看做常規莫隊中的l和r

然後利用組合數的可遞推性質就好了

相信改變m大家都會寫,n呢?

看圖:

技術分享圖片

我們發現,$S_n^m = S_{n-1}^m \times 2 - C_n^{m+1} + C_{n-1}^{m+1}$

(因為楊輝三角的性質)

所以n也可以遞推

套個莫隊就好了

代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#define
rii register int i #define rij register int j #define int long long const int p=1e9+7; using namespace std; struct que{ int n,m,ans,bh; }x[100005]; int ny[100005],jc[100005],jcny[100005],q,sy[100005],nn,nm,ans; void qny() { ny[1]=1; ny[0]=1; for(rii=2;i<=100000;i++) { ny[i]=(p-p/i)*ny[p%i]%p; } }
void jic() { jcny[0]=1; jc[1]=1; jcny[1]=1; for(rii=2;i<=100000;i++) { jc[i]=jc[i-1]*i; jc[i]%=p; jcny[i]=jcny[i-1]*ny[i]; jcny[i]%=p; } } void ycl() { qny(); jic(); } bool cmp1(que lk,que kl) { if(sy[lk.n]==sy[kl.n]) {
return lk.m<kl.m; } return lk.n<kl.n; } bool cmp2(que lk,que kl) { return lk.bh<kl.bh; } int c(int n,int m) { int kkk=jcny[m]; kkk*=jc[n]; kkk%=p; kkk*=jcny[n-m]; kkk%=p; return kkk; } void cn(int zl) { if(zl==1) { ans*=2; ans-=c(nn+1,nm+1); ans+=c(nn,nm+1); ans+=p; ans%=p; } if(zl==-1) { ans+=c(nn,nm+1); ans-=c(nn-1,nm+1); ans+=p; ans%=p; ans*=ny[2]; ans%=p; } } void cm(int zl) { if(zl==1) { ans+=c(nn,nm+1); } else { ans-=c(nn,nm); ans+=p; } ans%=p; } signed main() { freopen("sum.in","r",stdin); freopen("sum.out","w",stdout); ycl(); scanf("%lld",&q); scanf("%lld",&q); int len=316; for(rii=1;i<=100000;i++) { sy[i]=i/len+1; } for(rii=1;i<=q;i++) { scanf("%lld%lld",&x[i].n,&x[i].m); x[i].bh=i; } sort(x+1,x+q+1,cmp1); nn=1,nm=0,ans=1; for(rii=1;i<=q;i++) { if(x[i].m<nn) { while(nm>x[i].m) { cm(-1); nm--; } while(nm<x[i].m) { cm(1); nm++; } while(nn<x[i].n) { cn(1); nn++; } while(nn>x[i].n) { cn(-1); nn--; } } while(nn<x[i].n) { cn(1); nn++; } while(nn>x[i].n) { cn(-1); nn--; } while(nm>x[i].m) { cm(-1); nm--; } while(nm<x[i].m) { cm(1); nm++; } x[i].ans=ans; } sort(x+1,x+q+1,cmp2); for(rii=1;i<=q;i++) { printf("%lld\n",x[i].ans); } }

20181009noip HZ EZ兩校聯考sum(莫隊,組合數學)