倍增 质检习题

https://cdn.all-dream.com/user%2F1e3abe408f644377bc8c86a452d6e1a9%2F20190705_131230_zxc.mp4

1114: B15-倍增-质检

时间限制: 1 Sec  内存限制: 128 MB
提交: 1  解决: 1
[提交] [状态] [讨论版] [命题人:外部导入]

题目描述

输入

 
 

输出

样例输入 Copy

2
5 1 49
8 2 1 7 9
5 1 64
8 2 1 7 9

样例输出 Copy

2
1

提示

 
 
 
 

来源/分类

/*
1114: B15-倍增-质检
时间限制: 2 Sec  内存限制: 128 MB
提交: 7  解决: 3
[提交] [状态] [讨论版] [命题人:外部导入]
题目描述


输入

 
 
输出


样例输入 Copy

2
5 1 49
8 2 1 7 9
5 1 64
8 2 1 7 9
样例输出	Copy

2
1
提示

 
 
 
 
来源/分类

B15-倍增 
[提交] [状态]
GPLv2 licensed by QDOJ 2019
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
using namespace std;
int n,m;
long long k,a[500005],b[500005],c[500005],d[500005];
bool merge(long long b[],int l1,long long c[],int l2){
	int p1,p2,cnt=0;
	p1=p2=1;
	while(p1<=l1||p2<=l2){
		if(p1>l1)
			d[++cnt]=c[p2++];
		else if(p2>l2)
			d[++cnt]=b[p1++];
		else{
			if(b[p1]<c[p2])
				d[++cnt]=b[p1++];
			else
				d[++cnt]=c[p2++];
		}
	}
	long long sum=0;
	for(int i=1;i<=m&&2*i<=cnt;i++)
		sum+=(d[cnt-i+1]-d[i])*(d[cnt-i+1]-d[i]);
	if(sum>k)
		return 0;
	for(int i=1;i<=cnt;i++)
		b[i]=d[i];
	return 1;
}
int solve(int x){
	int l,r,len=1;
	l=r=x;
	b[1]=a[x];
	while(len>0){//倍增
		if(r+len>n)
			len=n-r;
		for(int i=r+1;i<=r+len;i++)
			c[i-r]=a[i];
		sort(c+1,c+len+1);
		if(merge(b,r-l+1,c,len))
			r+=len,len<<=1;
		else
			len>>=1;
		if(r>=n)
			break;
	}
	return r;
}
int main()
{
	int T;			
	cin>>T;
	while(T--){
		scanf("%d%d%lld",&n,&m,&k);
		for(int i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		int ans=0;
		for(int i=1;i<=n;i++){
			i=solve(i);
			ans++;
		}
		printf("%d\n",ans);
	}

	return 0;
}

  

posted @ 2019-07-06 09:46  DreamingBligo_Tido  阅读(198)  评论(0编辑  收藏  举报