首页 > 代码库 > hdu 5145
hdu 5145
[l,r] = (r-l+1)!/(num[1]!*num[2]!*num[3]!*……*num[n])
num[i] 表示 [l,r]中i 的个数
[l,r] = [l-1,r]*(r-l+1)/(++num[a[l]])
[l,r] = [l-1,r]*(num[a[l-1]]--)/(r-l+2)
预处理 [1..n]的逆元
离线读进所有询问,将l/sqrt(n)当第一关键字,r当第二关键字进行排序,然后直接暴力即可.
复杂度证明:
l/sqrt(n)<=sqrt(n) 也就是说最多只有sqrt(n)个“块”,快里面的r都是升序的 所以r在每个块中最多遍历n次 一共有sqrt(n)块,所以r遍历了n*sqrt(n)
每个块里面的l最多相差sqrt(n),所以l只要遍历sqrt(n)次,有t个询问,所以l遍历了t*sqrt(n)次
所以最坏的复杂度为O((t+n)*sqrt(n));
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 #define N 30000 7 const int mod = (int)(1e9+7); 8 long long nv[N+20]; 9 long long ans[N+20]; 10 long long res; 11 int L,R; 12 long long exgcd(long long a,long long b,long long &x,long long &y) 13 { 14 long long temp,d; 15 if (b==0) 16 { 17 x=1; 18 y=0; 19 return a; 20 } 21 d=exgcd(b,a%b,x,y); 22 temp=x-a/b*y; 23 x=y; 24 y=temp; 25 return d; 26 } 27 struct Node{ 28 int l,r,b,index; 29 }q[N+20]; 30 int a[N+20]; 31 int num[N+20]; 32 bool cmp(const Node &a,const Node &b){ 33 return a.b<b.b||(a.b==b.b&&a.r<b.r); 34 } 35 void add(int l,int r){ 36 if (l<L&&r<R){ 37 for (L=L-1;L>=l;L--){ 38 num[a[L]]++; 39 res = res * (R-L+1) % mod; 40 res = res * nv[num[a[L]]] % mod; 41 } 42 L++; 43 for (R=R;R>r;R--){ 44 res = res * num[a[R]] % mod; 45 res = res * nv[R-L+1] % mod; 46 num[a[R]]--; 47 } 48 } 49 if (l<L&&r>=R){ 50 for (L=L-1;L>=l;L--){ 51 num[a[L]]++; 52 res = res * (R-L+1) % mod; 53 res = res * nv[num[a[L]]] % mod; 54 } 55 L++; 56 for (R=R+1;R<=r;R++){ 57 num[a[R]]++; 58 res = res * (R-L+1) % mod; 59 res = res * nv[num[a[R]]] % mod; 60 } 61 R--; 62 } 63 if (l>=L&&r<R){ 64 for (R=R;R>r;R--){ 65 res = res * num[a[R]] % mod; 66 res = res * nv[R-L+1] % mod; 67 num[a[R]]--; 68 } 69 for (L=L;L<l;L++){ 70 res = res * num[a[L]] % mod; 71 res = res * nv[R-L+1] % mod; 72 num[a[L]]--; 73 } 74 } 75 if (l>=L&&r>=R){ 76 for (R=R+1;R<=r;R++){ 77 num[a[R]]++; 78 res = res * (R-L+1) % mod; 79 res = res * nv[num[a[R]]] % mod; 80 } 81 R--; 82 for (L=L;L<l;L++){ 83 res = res * num[a[L]] % mod; 84 res = res * nv[R-L+1] % mod; 85 num[a[L]]--; 86 } 87 } 88 } 89 int main(){ 90 for (int i=0;i<=N;i++){ 91 long long X,Y; 92 exgcd(i,mod,X,Y); 93 nv[i] = (X%mod+mod) % mod; 94 } 95 int t; 96 for (scanf("%d",&t);t;t--){ 97 int n,m; 98 scanf("%d%d",&n,&m); 99 for (int i=1;i<=n;i++) scanf("%d",&a[i]);100 int siz = (int)sqrt(n);101 for (int i=1;i<=m;i++){102 int l,r;103 scanf("%d%d",&l,&r);104 q[i].l = l;105 q[i].r = r;106 q[i].b = l/siz;107 q[i].index = i;108 }109 sort(q+1,q+1+m,cmp);110 L = 0, R = 0;111 res = 1;112 memset(num,0,sizeof(num));113 num[0] = 1;114 for (int i=1;i<=m;i++){115 add(q[i].l,q[i].r);116 ans[q[i].index] = res;117 }118 for (int i=1;i<=m;i++) printf("%I64d\n",ans[i]);119 }120 }
hdu 5145
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。