码迷,mamicode.com
首页 > 其他好文 > 详细

HDU_1175_莫队+逆元

时间:2016-10-06 20:08:27      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:

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_莫队+逆元

标签:

原文地址:http://www.cnblogs.com/zhurb/p/5934349.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!