Super Mario&&2012 ACM/ICPC Asia Regional Hangzhou Online

 这道题和树状数组求逆序数体很像,但是比赛的时候就是建立不好解题模型,比赛时好多人说需要离散化,看完别人的解题报告后才发现此题处理的便不是以前处理的值,这一题处理的是下标,用的是树状数组的离线算法,这题给我的感觉就是 自己的数状数组跟没学一个样,今后需要多多努力。

思路:分别对原始数组和要处理的值按从小到大排序,然后定义两个指针扫描排过序的数组,写两个条件判断,什么时候向树状数组插入,什么时候查询,

 

 

 

#include<iostream>
#include<stack>
#include<string.h>
#include<string>
#include<map>
#include<set>
#include<sstream>
#include<fstream>
#include<iterator>
#include<vector>
#include<algorithm>
#include<numeric>
#include<list>
#define N 100010
#define lowbit(x) (x&(-x))
#define CLR(arr,val) memset(arr,val,sizeof(arr))
using namespace std;
int s[N];
typedef struct node
{
	int val;
	int index;
}Node;
typedef struct snode
{
	int L;
	int R;
	int val;
	int index;
}Snode;
Node s1[N];
Snode s2[N];
int answer[N];
int n,m;
void add(int x)
{
	while(x<=n)
	{
		s[x]++;
		x+=lowbit(x);
	}
}
int sum(int x)
{
	int ans=0;
	while(x>0)
	{
		ans+=s[x];
		x-=lowbit(x);
	}
	return ans;
}
bool cmp(const Node& x,const Node& y)
{return x.val<y.val;}
bool cmp1(const Snode& x,const Snode& y)
{return x.val<y.val;}
void input(int& a)
{
	char ch;
	while((ch=getchar())>'9'||ch<'0') ;
	for(a=0;ch>='0'&&ch<='9';ch=getchar()) a=a*10+ch-'0';
}
int main()
{
	int T;
	input(T);
	for(int k=1;k<=T;++k)
	{
		input(n),input(m);
		for(int i=1;i<=n;++i) input(s1[i].val),s1[i].index=i;
		for(int i=0;i<m;++i)  input(s2[i].L),input(s2[i].R),input(s2[i].val),s2[i].L++,s2[i].R++,s2[i].index=i;
		sort(s1+1,s1+1+n,cmp);
		sort(s2,s2+m,cmp1);
		CLR(s,0);
		CLR(answer,0);
		int i=1,j=0;
		while(j<m)
		{
			while(i<=n)
				{
					 if(s1[i].val>s2[j].val) break;
			         add(s1[i].index);
			         i++;
			    }
			 while(j<m)
			 {

				 if(i<=n&&s1[i].val<=s2[j].val) break;
				 answer[s2[j].index]=sum(s2[j].R)-sum(s2[j].L-1);
				 j++;
			 }
		}
		printf("Case %d:\n",k);
		for(int i=0;i<m;++i) printf("%d\n",answer[i]);
	}return 0;
}


 

你可能感兴趣的:(Super Mario&&2012 ACM/ICPC Asia Regional Hangzhou Online)