zoukankan      html  css  js  c++  java
  • hdu 5145 NPY and girls 莫队+逆元

    NPY and girls

    Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


    Problem Description
    NPY's girlfriend blew him out!His honey doesn't love him any more!However, he has so many girlfriend candidates.Because there are too many girls and for the convenience of management, NPY numbered the girls from 1 to n.These girls are in different classes(some girls may be in the same class).And the i-th girl is in class ai.NPY wants to visit his girls frequently.Each time he visits some girls numbered consecutively from L to R in some order. He can only visit one girl every time he goes into a classroom,otherwise the girls may fight with each other(-_-!).And he can visit the class in any order.
    Here comes the problem,(NPY doesn't want to learn how to use excavator),he wonders how many different ways there can be in which he can visit his girls.The different ways are different means he visits these classrooms in different order.
     
    Input
    The first line contains the number of test cases T(1T10).
    For each test case,there are two integers n,m(0<n,m30000) in the first line.N is the number of girls,and M is the number of times that NPY want to visit his girls.
    The following single line contains N integers, a1,a2,a3,,an, which indicates the class number of each girl. (0<ai30000)
    The following m lines,each line contains two integers l,r(1lrn),which indicates the interval NPY wants to visit.
     
    Output
    For each visit,print how many ways can NPY visit his girls.Because the ans may be too large,print the ans mod 1000000007.
     
    Sample Input
    2 4 2 1 2 1 3 1 3 1 4 1 1 1 1 1
     
    Sample Output
    3 12 1
     
    Source
     
    思路:莫队;
       主要是更新;
       开始不知道怎么去重;
       然后看的别人的;
       c(n+1,m+1)=c(n,m)*(n+1)/(m+1);
       不太懂;
       不去重,有n+1个位置可以插入;
       然后将那么数字全取出来,可以插入的位置为个数+1
       相当于*(n+1)/(个数+1);
       trick:逆元需要打表;
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define pi (4*atan(1.0))
    #define mk make_pair
    #define eps 1e-7
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=3e4+10,M=4e6+10,inf=2147483647;
    const ll INF=1e18+10,mod=1000000007;
    
    ///   数组大小
    
    int pos[N];
    struct is
    {
        int l,r,now;
        bool operator < (const is &a)const
        {
            if(pos[l]!=pos[a.l])
                return pos[l]<pos[a.l];
            return r<a.r;
        }
    } s[N];
    
    int a[N];
    ll flag[N],ans,out[N],si;
    
    ll quick_pow(ll x,ll p)
    {
        if(!p) return 1;
        ll ans = quick_pow(x,p>>1);
        ans = ans*ans%mod;
        if(p & 1) ans = ans*x%mod;
        return ans;
    }
    
    ll inv[N];
    void add(int x)
    {
        si++;
        flag[a[x]]++;
        if(si<=0)return;
        ans=(ans*si)%mod;
        ans=(ans*inv[flag[a[x]]])%mod;
    }
    
    void del(int x)
    {
        if(si>0)ans=(ans*inv[si])%mod,ans=(ans*flag[a[x]])%mod;
        flag[a[x]]--;
        si--;
    }
    
    void xjhz()
    {
        inv[1] = 1;
        for (int i=2; i<=30000; ++i) {
            inv[i] =  (mod - mod / i) * inv[mod%i] % mod;
        }
    }
    
    void init()
    {
        ans=1;
        si=0;
        memset(flag,0,sizeof(flag));
    }
    int main()
    {
        xjhz();
        int T;
        scanf("%d",&T);
        while(T--)
        {
            init();
            int n,q;
            scanf("%d%d",&n,&q);
            int k=sqrt(n);
            for(int i=1; i<=n; i++)
                scanf("%d",&a[i]),pos[i]=(i-1)/k+1;
            for(int i=1; i<=q; i++)
                scanf("%d%d",&s[i].l,&s[i].r),s[i].now=i;
            sort(s+1,s+1+q);
            int L=1,R=0;
            for(int i=1; i<=q; i++)
            {
                while(L<s[i].l)
                {
                    del(L);
                    L++;
                }
                while(L>s[i].l)
                {
                    L--;
                    add(L);
                }
                while(R>s[i].r)
                {
                    del(R);
                    R--;
                }
                while(R<s[i].r)
                {
                    R++;
                    add(R);
                }
                out[s[i].now]=ans;
            }
            for(int i=1; i<=q; i++)
                printf("%lld
    ",out[i]);
        }
        return 0;
    }
       
  • 相关阅读:
    Oracle基础底细数据圭臬标准标准存储魔术浅析(四)——ROWID圭臬标准标准(二)
    Oracle根蒂根基数据典范存储格局浅析(三)——日期典范(一)
    Oracle 数据库注入技能
    Oracle 装配的时分java状况设置选项
    Oracle底子根基数据圭臬尺度存储格式浅析(三)——日期圭臬尺度(四)
    oracle不同数据模范存储空间的实例较量
    RHEL AS 3 安排及启动 Oracle10g 指南
    ORACLE数据库容灾复制措置赏罚方案share Plex
    Oracle 常用函数
    Oracle基本数据标准存储样式浅析(二)——数字标准
  • 原文地址:https://www.cnblogs.com/jhz033/p/6701620.html
Copyright © 2011-2022 走看看