poj 2104 (暴力or划分树)

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/ergedathouder/article/details/52182890

题意就是给m个数,n个询问,问在从a到b的区间里第k大的数是多少

这题有二十秒,纯暴力就可以过~~~和线段树什么的时间还差不多

上代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
	int zhi;int weizhi;//值和位置
};
node a[100010];
int cmp(node x,node y){
	return x.zhi<y.zhi;//这个函数表示以zhi为标准进行排序,附带着把weizhi移过去;
}
int main(){
	int i,j,m,n,k,x,y,z;
	scanf("%d%d",&m,&n);
	for(i=1;i<=m;i++){
	scanf("%d",&a[i].zhi);
	a[i].weizhi=i;//记录位置
	}
	sort(a+1,a+m+1,cmp);//排序
	for(i=1;i<=n;i++){
		scanf("%d%d%d",&x,&y,&z);
		for(j=1;j<=m;j++){
		if(a[j].weizhi>=x&&a[j].weizhi<=y)z--;//从第一个往上找,找到一个在区间内的,z减一个直到找到第k大的;
		if(z==0){printf("%d\n",a[j].zhi);break;}}
	}
	return 0;
} 

接下来是划分树的正解:

至于划分数可以看网上的PPT:

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int a[100010];
struct node{
	int p[100010],o[100010];
};
node t[100];
void jianshu(int s,int e,int c){//s是start,e是end,c是层次; 
	if(s==e)return;//若每个层次只有一个数,返回; 
	int mid=(s+e)/2;
	int x=s;
	int y=mid+1;
	int sum=0;//计数,处理有多个a[mid]相同的情况
	int l=0;//记录有多少个数被划分到左边
	for(int i=mid;a[i]==a[mid];i--){
		sum++;
	}
	for(int i=s;i<=e;i++){
		if(a[mid]>t[c].o[i]){
			l++;
			t[c+1].o[x++]=t[c].o[i];
			t[c].p[i]=l;
			continue;//记得加
		}
		if(a[mid]<t[c].o[i]){
			t[c+1].o[y++]=t[c].o[i];
			t[c].p[i]=l;
			continue;
		}
		if(a[mid]==t[c].o[i]&&sum){
			sum--;
			l++;
			t[c+1].o[x++]=t[c].o[i];
			t[c].p[i]=l;
			continue;
		}
		else {
			t[c+1].o[y++]=t[c].o[i];
			t[c].p[i]=l;
		}
	}
	jianshu(s,mid,c+1);
	jianshu(mid+1,e,c+1);
}
int xunwen(int s,int e,int k,int j,int th,int ceng){
	if(s==e)return t[ceng].o[s];
	int mid=(k+j)/2;
	int x;int y;
	if(s==k){x=0;y=t[ceng].p[e];}
	else{x=t[ceng].p[s-1];
	y=t[ceng].p[e]-x;}
	if(y>=th){
		return xunwen(k+x,k+x+y-1,k,mid,th,ceng+1);
	}
	else return xunwen(mid+s-x-k+1,mid+e-x-y-k+1,mid+1,j,th-y,ceng+1);
}
int main(){
	int i,j,k,m,n,x,y,z;
	scanf("%d%d",&m,&n);
	for(i=1;i<=m;i++){
		scanf("%d",&t[1].o[i]);
		a[i]=t[1].o[i];
	}
	sort(a+1,a+m+1);
	jianshu(1,m,1);
	while(n--)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		printf("%d\n",xunwen(x,y,1,m,z,1));
	}
	return 0;
}


没有更多推荐了,返回首页