首页 > 代码库 > HDU_1175_莫队+逆元
HDU_1175_莫队+逆元
http://acm.hdu.edu.cn/showproblem.php?pid=5145
初探莫队,就是离线排序后的暴力,但是效率大大提高,中间要除法取模,所以用到了逆元。
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#define LL long long#define MOD 1000000007 using namespace std;int a[30005],num[30005],n,m,sizee;LL ans[30005],inv[30005];struct node{ int l,r,num,belong;}query[30005];void init(){ for(int i = 1;i <= 30000;i++) { LL temp = 1,x = i; int pow = MOD-2; while(pow) { if(pow%2) temp = temp*x%MOD; x = x*x%MOD; pow /= 2; } inv[i] = temp; }}int cmp(node x,node y){ if(x.belong == y.belong) return x.r < y.r; return x.l<y.l;}int main(){ init(); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); sizee = sqrt(n); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); for(int i = 1;i <= m;i++) { scanf("%d%d",&query[i].l,&query[i].r); query[i].num = i; query[i].belong = (query[i].l-1)/sizee+1; } sort(query+1,query+1+m,cmp); memset(num,0,sizeof(num)); int ll = 1,rr = 1; LL now = 1; num[a[1]]++; for(int i = 1;i <= m;i++) { while(rr < query[i].r) { rr++; num[a[rr]]++; now = now*(rr-ll+1)%MOD*inv[num[a[rr]]]%MOD; } while(ll > query[i].l) { ll--; num[a[ll]]++; now = now*(rr-ll+1)%MOD*inv[num[a[ll]]]%MOD; } while(ll < query[i].l) { now = now*num[a[ll]]%MOD*inv[rr-ll+1]%MOD; num[a[ll]]--; ll++; } while(rr > query[i].r) { now = now*num[a[rr]]%MOD*inv[rr-ll+1]%MOD; num[a[rr]]--; rr--; } ans[query[i].num] = now; } for(int i = 1;i <= m;i++) printf("%lld\n",ans[i]); } return 0;}
HDU_1175_莫队+逆元
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。