zoukankan      html  css  js  c++  java
  • 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
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    非旋Treap——fhq treap
    LCA
    树链剖分
    复习计划
    BZOJ2565: 最长双回文串(回文树)
    回文自动机
    luogu P3796 【模板】AC自动机(加强版)
    【BZOJ2908】 又是nand
    【HDU2460】 Network
    【CF786B】 Legacy
  • 原文地址:https://www.cnblogs.com/zhurb/p/5934349.html
Copyright © 2011-2022 走看看