HDOJ 5145 NPY and girls

#include <iostream>
#include <queue> 
#include <stack> 
#include <map> 
#include <set> 
#include <bitset> 
#include <cstdio> 
#include <algorithm> 
#include <cstring> 
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 30005
#define maxm 2000005
#define eps 1e-10
#define mod 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid 
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
//#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head

struct Point
{
	int l, r, k, id;
	LL ans;
	bool operator < (const Point& b) const {
		return k == b.k ? r < b.r : k < b.k;
	}
}p[maxn];
LL f[maxn];
LL g[maxn];
int a[maxn];
int c[maxn];
LL res[maxn];
int cnt, n, m;
LL sum;

void init(void)
{
	f[0] = 1;
	g[0] = powmod(f[0], mod-2);
	for(int i = 1; i <= 30000; i++) f[i] = i;
	for(int i = 1; i <= 30000; i++) g[i] = powmod(f[i], mod-2);
}

void read(void)
{
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for(int i = 1; i <= m; i++) scanf("%d%d", &p[i].l, &p[i].r);
	for(int i = 1; i <= m; i++) p[i].id = i;
}

void add(int x)
{
	sum = sum * f[++cnt] % mod * g[++c[x]] % mod;
}

void del(int x)
{
	sum = sum * f[c[x]--] % mod * g[cnt--] % mod;
}

void work(void)
{
	int s = sqrt((double)30000);
	for(int i = 1; i <= m; i++) p[i].k = p[i].l / s;
	sort(p + 1, p + m + 1);
	for(int i = 1; i <= m; i++) {
		int l = p[i].l, r = p[i].r;
		memset(c, 0, sizeof c);
		sum = 1, cnt = 0;
		for(int j = l; j <= r; j++) add(a[j]);
		p[i].ans = sum;
		while(i < m && p[i].k == p[i+1].k) {
			i++;
			while(r < p[i].r) add(a[++r]);
			while(l > p[i].l) add(a[--l]);
			while(l < p[i].l) del(a[l++]);
			p[i].ans = sum;
		}
	}
	for(int i = 1; i <= m; i++) res[p[i].id] = p[i].ans;
	for(int i = 1; i <= m; i++) printf("%I64d\n", res[i]);
}

int main(void)
{
	int _;
	init();	
	while(scanf("%d", &_)!=EOF) {
		while(_--) {
			read();
			work();
		}
	}


	return 0;
}

你可能感兴趣的:(HDU)