数列区间询问中的分块思想CF86D,BC#22-1004-NPY and girls


学自:http://www.cnblogs.com/Lyush/archive/2013/08/16/3263247.html

CF 86D powerful array


代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))

struct node
{
	ll l, r, b, id;
}p[200010];
ll ans[200020];
ll q[200020];
ll h[1000020];
bool cmp(node a, node b)
{
	if (a.b == b.b) return a.r < b.r;
	return a.l < b.l;
}
//上下两种排序方式应该都可以
bool comp(node a, node b)
{
	if (a.b == b.b) return a.r < b.r;
	return a.b < b.b;
}
int main()
{
	int n, m;
	cin >> n >> m;
	int i, j, k;
	for (i = 1; i <= n; i++)
	{
		cin >> q[i];
	}
	ll sp = (ll)sqrt(1.0*n);
	for (i = 1; i <= m; i++)
	{
		cin >> p[i].l >> p[i].r;
		p[i].id = i;
		p[i].b = p[i].l / sp;
	}
	sort(p + 1, p + 1 + m, comp);
	ll l = p[1].l, r = p[1].r;
	ll sum = 0;
	mem(h, 0);
	for (i = l; i <= r; i++)
	{
		ll t = q[i];
		sum += 2LL * h[t] * t + t;
		h[t]++;
	}
	ans[p[1].id] = sum;
	for (i = 2; i <= m; i++)
	{
		int L = p[i].l, R = p[i].r;
		while (r < R)
		{
			r++;
			ll t = q[r];
			sum += 2LL * h[t] * t + t;
			h[t]++;
		}
		while (l > L)
		{
			l--;
			ll t = q[l];
			sum+=2LL * h[t] * t + t;
			h[t]++;
		}
		while (r>R)
		{
			ll t = q[r];
			sum += -2LL * h[t] * t + t;
			r--;
			h[t]--;
		}
		while (l < L)
		{
			ll t = q[l];
			sum += -2LL * h[t] * t + t;
			l++;
			h[t]--;
		}
		ans[p[i].id] = sum;
	}
	for (i = 1; i <= m; i++)
		printf("%I64d\n",ans[i]);
	//system("pause");
}


BC#22 1004 NPY and girls


代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod = 1e9 + 7;

struct node
{
	ll l, r, b, id;
}p[30010];
ll ans[30020];
ll q[30020];
ll h[30020];
ll in[30010];
ll inv(ll n, ll m)
{
	ll b = 1;
	while (m)
	{
		if (m & 1) b = b*n%mod;
		n = n*n%mod;
		m >>= 1;
	}
	return b;
}
bool cmp(node a, node b)
{
	if (a.b == b.b) return a.r < b.r;
	return a.l < b.l;
}
//上下两种排序方式应该都可以,貌似下面的更快些~
bool comp(node a, node b)
{
	if (a.b == b.b) return a.r < b.r;
	return a.b < b.b;
}
int main()
{
	int t, n, m;
	int i, j, k;
	scanf("%d",&t);
	for (i = 1; i <= 30000; i++)
		in[i] = inv(i, mod - 2);
	while (t--)
	{
		scanf("%d%d",&n,&m);
		for (i = 1; i <= n; i++)
		{
			scanf("%I64d",&q[i]);
		}
		ll sp = (ll)sqrt(1.0*n);
		for (i = 1; i <= m; i++)
		{
			scanf("%I64d%I64d", &p[i].l, &p[i].r);
			p[i].id = i;
			p[i].b = p[i].l / sp;
		}
		sort(p+1,p+1+m,comp);
		int l = p[1].l, r = p[1].r;
		ll sz = 0;
		ll sum = 1;
		mem(h, 0);
		for (i = l; i <= r; i++)
		{
			sz++;
			ll te = q[i];
			h[te]++;
			sum = sum*sz%mod*in[h[te]] % mod;
		}
		ans[p[1].id] = sum;
		for (i = 2; i <= m; i++)
		{
			ll L = p[i].l, R = p[i].r;
			while (r < R)
			{
				sz++;
				r++;
				ll te = q[r];
				h[te]++;
				sum = sum*sz%mod*in[h[te]] % mod;
			}
			while (l>L)
			{
				sz++;
				l--;
				ll te = q[l];
				h[te]++;
				sum = sum*sz%mod*in[h[te]] % mod;
			}
			while (r > R)
			{
				ll te = q[r];
				sum = sum*h[te] % mod*in[sz] % mod;
				sz--;
				h[te]--;
				r--;
			}
			while (l < L)
			{
				ll te = q[l];
				sum = sum*h[te] % mod*in[sz] % mod;
				sz--;
				h[te]--;
				l++;
			}
			ans[p[i].id] = sum;
		}
		for (i = 1; i <= m; i++)
			printf("%I64d\n",ans[i]);
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值