HDU - 5145 NPY and girls

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

大概题意:

一个人有n个女朋友,每个女朋友都有一个班级a[i],现有m个询问。每个询问有一个区间范围[L,R],表示这个人想要约[L,R]范围内的女生有几种约法。(第L个女生到第R个女生的区间,而不是班级).
单组询问[L,R]

(R-L+1)!/[(num[x1]!)(num[x2]!)……(num[xn]!)] ,x1,x2,……,xn为[L,R]区间内出现过的所有不相同的数,num[]表示该数出现的次数.

莫对(处理区间问题)+组合数学

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5145

#include<stdio.h>
#include<iostream>
#include<string.h>
#include <stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL mod = 1000000007;
const int N = 30005;
int n,m;
LL a[N];
LL inv[N];
LL Hash[N];
LL res[N];
struct Node{
    int l,r,sqr,id;
}node[N];
int cmp(Node a,Node b){
    if(a.sqr==b.sqr) return a.r<b.r;
    return a.l<b.l;
}
LL pow_mod(LL a,LL n){
    LL ans = 1;
    while(n){
        if(n&1) ans = ans*a%mod;
        a = a*a%mod;
        n>>=1;
    }
    return ans;
}
LL getinv(int x){
    return pow_mod(x,mod-2);
}
int main()
{
    int tcase;
    scanf("%d",&tcase);
    for(int i=1;i<=N;i++){
        inv[i] = getinv(i);
    }
    while(tcase--)
    {
        scanf("%d%d",&n,&m);
        int k = (int)sqrt(n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&node[i].l,&node[i].r);
            node[i].id = i;
            node[i].sqr = node[i].l/k;
        }
        sort(node+1,node+m+1,cmp);
        memset(Hash,0,sizeof(Hash));
        int l=1,r = 1;
        Hash[a[1]]++;
        LL ans = 1;
        for(int i=1;i<=m;i++){
            while(r<node[i].r){
                r++;
                Hash[a[r]]++;
                ans = ans*(r-l+1)%mod*inv[Hash[a[r]]]%mod;
            }
            while(l>node[i].l){
                l--;
                Hash[a[l]]++;
                ans = ans*(r-l+1)%mod*inv[Hash[a[l]]]%mod;
            }
            while(r>node[i].r){
                ans = ans*Hash[a[r]]%mod*inv[r-l+1]%mod;
                Hash[a[r]]--;
                r--;
            }
            while(l<node[i].l){
                ans = ans*Hash[a[l]]%mod*inv[r-l+1]%mod;
                Hash[a[l]]--;
                l++;
            }
            res[node[i].id] = ans;
        }
        for(int i=1;i<=m;i++){
            printf("%lld\n",res[i]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38295645/article/details/90049564
今日推荐