zoukankan      html  css  js  c++  java
  • NPY and girls-HDU5145莫队算法

    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(1≤T≤10).
    For each test case,there are two integers n,m(0 < n,m≤30000) 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< ai ≤30000)
    The following m lines,each line contains two integers l,r(1≤l≤r≤n),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

    莫队算法处理区间查询问题,对于[L,R]区间中的组合所有的情况是(R-L+!)!/(num[i]!num[j]!….),所以可以根据[L,R]的情况来推其他的情况。

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    const int Max = 31000;
    
    const int Mod =1e9+7; 
    
    typedef struct node
    {
        int l,r,Id;
    
        int L;
    
        bool operator < (const node &a)const
        {
            return L<a.L||(L==a.L&&r<a.r); 
        }
    }Node;
    
    int a[Max];
    
    Node s[Max];
    
    LL ans[Max];
    
    LL Inv[Max];
    
    int num[Max];
    
    LL  Pow(LL n,LL m)
    {
        LL ans = 1;
    
        while(m)
        {
            if(m&1)
            {
                ans = (ans*n)%Mod;
            }
    
            n = (n*n)%Mod;
    
            m>>=1;
        }
    
        return ans;
    }
    
    void Init() // 求逆元
    {
        for(int i = 0;i<=30000;i++)
        {
            Inv[i]  = Pow(i,Mod-2);
    
        }
    
    }
    
    
    
    int main()
    {
        Init();
    
        int T;
    
        int n,m;
    
        scanf("%d",&T);
    
        while(T--)
        {
            memset(num,0,sizeof(num));
    
            scanf("%d %d",&n,&m);
    
            int k = sqrt(n);
    
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
            }
            for(int i=0;i<m;i++)
            {
                scanf("%d %d",&s[i].l,&s[i].r);
    
                s[i].L = s[i].l/k;
    
                s[i].Id = i;
            }
    
            sort(s,s+m);
    
            LL l=1,r=1;
    
            num[a[1]]++;
    
            LL res = 1;
    
            for(int i=0;i<m;i++)
            {
                while(r<s[i].r)
                {
                    r++;
    
                    num[a[r]]++;
    
                    res = (((r-l+1)*res)%Mod*Inv[num[a[r]]])%Mod;
    
                }
                while(r>s[i].r)
                {
    
                    res = ((res*num[a[r]])%Mod*Inv[r-l+1])%Mod;
    
                    num[a[r]]--;
    
                    r--;
                }
    
                while(l>s[i].l)
                {
                    l--;
    
                    num[a[l]]++;
    
                    res = (((r-l+1)*res)%Mod*Inv[num[a[l]]])%Mod;
    
                }
    
                while(l<s[i].l)
                {
                    res = ((res*num[a[l]])%Mod*Inv[r-l+1])%Mod;
    
                    num[a[l]]--;
    
                    l++;
                }
    
                ans[s[i].Id] = res;
            }
            for(int i=0;i<m;i++)
            {
                printf("%lld
    ",ans[i]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    用Actionscript3.0编写的伪3D文字旋转
    iis权限设置
    SQL 不能通过IP正常连接终极解决方案
    创建一个非常简单的NHibernate的应用
    解决“System.Data.OracleClient需要Oracle客户端软件8.1.7或更高版本”
    详细讲解提高数据库查询效率的实用方法、外键关于性能
    解决ERRORORA12514:TNS:监听程序当前无法识别连接描述符中请求的服务
    session丢失问题
    Jquery AJAX WebService处理方式 demo
    DIV模拟弹出窗口(支持拖动)
  • 原文地址:https://www.cnblogs.com/juechen/p/5255863.html
Copyright © 2011-2022 走看看