CodeForces 811B Vladik and Complicated Book

离线,树状数组。

数据范围好像有点小,直接暴力可以过的。

我直接上了$n,Q≤100000$的做法:只需要判断区间上比$x$小的数字有几个即可,可以对询问进行离线操作,从左到右一个一个数字插入到树状数组中。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
using namespace std;

int n,m;
struct X
{
	int id;
	int op;
	int pos;
	int val;
	int y;
}s[20010];
int sz;
int ans[10010][2];
int c[10100],a[10100];

int lowbit(int x)
{
	return x&(-x);
}

void update(int x)
{
	while(x<=10000)
	{
		c[x]++;
		x = x+lowbit(x);
	}
}

int get(int x)
{
	int res = 0;

	while(x>0)
	{
		res = res + c[x];
		x = x-lowbit(x);
	}
	return res;
}

bool cmp(X a,X b)
{
	return a.pos<b.pos;
}

bool cmp2(X a,X b)
{
	if(a.id == b.id) return a.op < b.op;
	return a.id < b.id;
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
	{
		int L,R,v; scanf("%d%d%d",&L,&R,&v);
		s[sz].id = i;
		s[sz].op = 0;
		s[sz].pos = L-1;
		s[sz].val = a[v];
		s[sz].y = v;
		sz++;
		s[sz].id = i;
		s[sz].op = 1;
		s[sz].pos = R;
		s[sz].val = a[v];
		s[sz].y = v;
		sz++;
	}

	sort(s,s+sz,cmp);


	int p = 0;
	for(int i=0;i<=n;i++)
	{
		if(i>0) update(a[i]);

		while(1)
		{
			if(p<sz && s[p].pos==i)
			{
				ans[s[p].id][s[p].op] = get(s[p].val-1);
				p++;
			}
			else break;
		}
	}

	sort(s,s+sz,cmp2);

	int id = 0;
	for(int i=0;i<sz;i=i+2)
	{
		id++;
		int num1 = ans[id][1] - ans[id][0];
		int num2 = s[i].y - s[i].pos - 1;
		if(num1 == num2) printf("Yes\n");
		else printf("No\n");
	}

	return 0;
}
posted @ 2017-06-01 19:25 Fighting_Heart 阅读(...) 评论(...) 编辑 收藏