首页 > 代码库 > Liers 树状数组+中国剩余定理
Liers 树状数组+中国剩余定理
Liers
Time Limit: 14000/7000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
SubmitStatus
Problem Description
有N个人,其中有若干个人一起参加了舞会,现在想知道哪些人有可能参加了舞会,你问了N个人,第i个人说参加舞会的人数在[Li,Ri]区间的一个数,问有多少种合法的舞会人数方案?所谓合法方案是指,参加舞会的所有人说的都是真话,即参加舞会的人中,舞会总人数符合所有参加舞会的人的话语(不一定符合没有参加舞会的人的话语),即在其区间中。假设参加了舞会的人说的都是真话。
Input
多组数据,每组数据:
第一行,N(1 <= N <= 10^6),总人数
从2到N + 1行,每行两个正整数,L,R,表示第i个人说的,舞会总人数为[L,R]中的一个数 -2^31 <= L,R <= 2^31 - 1(int)
Output
每组数据输出一行,总合法数 % 20140717
Sample Input
31 11 11 130 20 20 2
Sample Output
36
Hint
第二个样例说明,舞会可能只有一个人参加,这样由3种情况,1或者2或者3,也可能2个人参加,(1,2)或(1,3)或(2,3),注意,一个合理的舞会至少需要有一个人
1 #include <iostream> 2 #include <stdio.h> 3 #include <math.h> 4 #include <string.h> 5 #include <algorithm> 6 using namespace std; 7 #define mod 20140717LL 8 #define ll long long 9 typedef struct people 10 { 11 int l,r; 12 } people; 13 people p[1000001]; 14 int b[1000001],n; 15 short int a1[46][46]= {0},a2[110][110]= {0},a3[4599][4599]= {0}; 16 void init() 17 { 18 int i,j; 19 a1[0][0]=a2[0][0]=a3[0][0]=1; 20 for(i=1; i<4599; i++) 21 { 22 a3[i][i]=a3[i][0]=1; 23 for(j=1; j<i; j++) 24 a3[i][j]=a3[i-1][j-1]+a3[i-1][j],a3[i][j]%=4591; 25 } 26 for(i=1; i<110; i++) 27 { 28 a2[i][i]=a2[i][0]=1; 29 for(j=1; j<i; j++) 30 a2[i][j]=a2[i-1][j-1]+a2[i-1][j],a2[i][j]%=107; 31 } 32 for(i=1; i<46; i++) 33 { 34 a1[i][i]=a1[i][0]=1; 35 for(j=1; j<i; j++) 36 a1[i][j]=a1[i-1][j-1]+a1[i-1][j],a1[i][j]%=41; 37 } 38 } 39 int lowbit(int x) 40 { 41 return x&(-x); 42 } 43 void update(int x,int z) 44 { 45 while(x>0) 46 { 47 b[x]+=z; 48 x-=lowbit(x); 49 } 50 } 51 int query(int x) 52 { 53 int sum=0; 54 while(x<=n) 55 { 56 sum+=b[x]; 57 x+=lowbit(x); 58 } 59 return sum; 60 } 61 int fun1(int m,int x,int y) 62 { 63 int ans=1; 64 while(x) 65 { 66 if(y==41) 67 ans*=a1[m%y][x%y]; 68 else if(y==107) 69 ans*=a2[m%y][x%y]; 70 else ans*=a3[m%y][x%y]; 71 m/=y,x/=y; 72 } 73 return ans; 74 } 75 int fun(int m,int x) 76 { 77 ll m1,m2,m3; 78 m1=fun1(m,x,41); 79 m2=fun1(m,x,107); 80 m3=fun1(m,x,4591); 81 int ans=((m1*8842266LL)%mod+(m2*1129386LL)%mod+(m3*10169066LL)%mod)%mod; 82 return ans; 83 } 84 int main() 85 { 86 // freopen("in.txt","r",stdin); 87 init(); 88 int i,j,ans,m; 89 while(scanf("%d",&n)!=EOF) 90 { 91 for(i=0; i<n; i++) 92 { 93 scanf("%d%d",&p[i].l,&p[i].r); 94 if(p[i].l<=0)p[i].l=1; 95 if(p[i].l>n)p[i].r=n; 96 if(p[i].r<=0)p[i].r=1; 97 if(p[i].r>n)p[i].r=n; 98 } 99 memset(b,0,sizeof(b));100 for(i=0; i<n; i++)101 {102 update(p[i].r,1);103 update(p[i].l-1,-1);104 }105 ans=0;106 for(i=1; i<=n; i++)107 {108 m=query(i);109 if(m>=i)110 ans+=fun(m,i),ans%=mod;111 }112 printf("%d\n",ans%mod);113 }114 115 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。