poj 3368 Frequent values(RMQ)

题目链接

给一个单增序列

求所给的区间内数字最多的重复次数。

思路

我一开始想歪了,但是居然还是ac了。

mx[i][j]=Max(mx[i][j-1],mx[i+(1<<(j-1))][j-1])

这个Max操作很复杂,因为我mx[i][j]是一个结构体,存放最大值,左端值,左端重复个数,右端值,右端重复个数。要比较最大值是2个区间的最大和他们中间连起来后可能出现的最大值。然后更新左端值,左端重复个数,右端值,右端重复个数。

开始没什么问题,但是最后到查询区间[x,y]的时候我卡主了。因为我这个算法,区间不能重复。而我们一贯采用的Max(mn[x][k],mn[y-(1<

时间很有意思


此题限时2000ms.

所以我贴此题不是想说什么,只是想警示自己,模板模板,是要灵活运用的,明明可以有个操作简化很多的,却因为脑子太直白,太不了解而自己给自己挖坑

代码

//这样做能过简直是万幸//
/*
可以这样做,首先预处理每个位子,让b[i]存i这个位子上的数出现的个数
对于样例
       -1 -1 1 1 1 1 3 10 10 10 
则存为  1  2 1 2 3 4 1 1  2  3
那么每次取区间的时候x,y那么对于等于a[x]的所以位置都要减去b[x]-1的值,
即把b[x]=1,b[x+1]=2……b[t-1]=t-1-x+1,直到a[t]!=a[x]为止。
这样就可以直接rmq了 
*/ 

#include
#include
#include	
#include
#include
#include
#include
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
int a[maxn];
struct bz{
	int data;
	int left,right;
	int left_number,right_number;
};
bz mx[maxn][20];
bz Max(bz x,bz y){
	bz ans;
	ans.left=x.left;
	ans.right=y.right;
	ans.data=max(x.data,y.data);
	int mid=0;
	if(x.right==y.left){
		mid=x.right_number+y.left_number;
	}
	ans.data=max(ans.data,mid);
	if(x.left==x.right){
		ans.left_number=max(mid,x.left_number);
	}else{
		ans.left_number=x.left_number;
	}
	if(y.left==y.right){
		ans.right_number=max(mid,y.right_number);
	}else{
		ans.right_number=y.right_number;
	}
	return ans;
}
int Pow(int a,int n){
	int ans=1;
	while(n>0){
		if(n%2==1) ans*=a;
		a=a*a;
		n=n/2;
	}
	return ans;
}
int main(){
	int n,q;
	while(~scanf("%d",&n)&&n!=0){
		scanf("%d",&q);
		mem(mx,0);
		for(int i=0;i0){
					if(cha%2==1) a[i]=1;
					else a[i]=0;
					cha=cha/2;
					i++;
				}
				int flag=1;
				for(i=i-1;i>=0;i--){
//					cout<

你可能感兴趣的:(个人的解题,总结和反思)