【HDOJ6333】Harvest of Apples(莫队)

题意:

给定T组询问,每组有两个数字n和m,求sigma i=0..m c(n,i) 答案对1e9+7取模

T<=1e5

1<=n,m<=1e5

思路:

注意要先变n再变m,否则会因n太小有些组合数会丢失

关键点在于n的转移,m的转移谁都会

预处理数组越界要小心

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned int uint;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> PII;
 16 typedef vector<int> VI;
 17 #define fi first
 18 #define se second 
 19 #define MP make_pair
 20 #define MOD 1000000007
 21 #define N   110000
 22 
 23 struct data{int x,y,id;}a[N];
 24 ll ans[N+10],fac[N+10],inv[N+10],inv2;
 25 int pos[N+10],m;
 26  
 27 bool cmp(data a,data b)
 28 {
 29     if(pos[a.x]==pos[b.x]) return a.y<b.y;
 30     return a.x<b.x;
 31 }
 32 
 33 int read()
 34 { 
 35    int v=0,f=1;
 36    char c=getchar();
 37    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 38    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 39    return v*f;
 40 }
 41 
 42 ll c(int x,int y)
 43 {
 44     ll t=fac[x]*inv[y]%MOD*inv[x-y]%MOD;
 45     return t;
 46 }
 47 
 48 void solve()
 49 {
 50     ll sum=0; 
 51     for(int i=0;i<=a[1].y;i++) sum=(sum+c(a[1].x,i))%MOD;
 52     int nowx=a[1].x,nowy=a[1].y; 
 53     ans[a[1].id]=sum;
 54     for(int i=2;i<=m;i++)
 55     {
 56         while(nowx>a[i].x)
 57         {
 58             sum=(sum+c(nowx-1,nowy))%MOD;
 59             sum=sum*inv2%MOD;
 60             nowx--;
 61           }
 62           while(nowx<a[i].x)
 63         {
 64             sum=(sum*2-c(nowx,nowy)+MOD)%MOD;
 65             nowx++;
 66         }
 67         while(nowy>a[i].y)
 68         {
 69             sum=(sum-c(nowx,nowy)+MOD)%MOD;
 70             nowy--;
 71         }
 72         while(nowy<a[i].y)
 73         {
 74             sum=(sum+c(nowx,nowy+1)+MOD)%MOD;
 75             nowy++;
 76         }
 77         ans[a[i].id]=sum;
 78     } 
 79 } 
 80         
 81 void init()
 82 {
 83     fac[0]=1;
 84     for(int i=1;i<=N;i++) fac[i]=fac[i-1]*i%MOD;
 85     inv[0]=inv[1]=1;
 86     for(int i=2;i<=N;i++) inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD; 
 87     inv2=inv[2];
 88     for(int i=1;i<=N;i++) inv[i]=inv[i-1]*inv[i]%MOD; 
 89     int block=int(sqrt(N));
 90     for(int i=1;i<=N;i++) pos[i]=(i-1)/block+1; 
 91 }
 92  
 93 int main()
 94 {
 95       //freopen("1.in","r",stdin);
 96     //freopen("1.out","w",stdout);
 97     scanf("%d",&m);
 98     for(int i=1;i<=m;i++) 
 99     {
100         scanf("%d%d",&a[i].x,&a[i].y);
101         a[i].id=i;
102     }
103     init();
104     sort(a+1,a+m+1,cmp);
105     solve();
106     for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
107     return 0;
108 }

 

posted on 2018-08-02 15:43  myx12345  阅读(113)  评论(0编辑  收藏  举报

导航