Genius ACM HihoCoder - 1384 倍增/归并排序模板
倍增可行长度和直接二分都可以保证对于每个左端点至多log次找到最远右端点
但是倍增的过程中所需要计算的长度是从小逐渐变大的,而且可以利用前一步倍增的有序数组做一轮归并,
整体就比直接二分右端点所需要计算的长度快一个log
//#include<bits/stdc++.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
#include<bitset>
using namespace std; //
#define ll long long
#define pb push_back
#define FOR(a) for(int i=1;i<=a;i++)
#define sqr(a) (a)*(a)
#define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
ll qp(ll a,ll b,ll mod){
ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
}
struct DOT{ll x;ll y;};
const int dx[4]={0,0,-1,1};
const int dy[4]={1,-1,0,0};
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
/******************************************************/
namespace fastIO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
#define ll long long
//fread->read
bool IOerror=0;
inline char nc(){
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if (p1==pend){
p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
if (pend==p1){IOerror=1;return -1;}
//{printf("IO error!\n");system("pause");for (;;);exit(0);}
}
return *p1++;
}
inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
inline void read(int &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(ll &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(double &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (ch=='.'){
double tmp=1; ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
}
if (sign)x=-x;
}
inline void read(char *s){
char ch=nc();
for (;blank(ch);ch=nc());
if (IOerror)return;
for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
*s=0;
}
inline void read(char &c){
for (c=nc();blank(c);c=nc());
if (IOerror){c=-1;return;}
}
#undef OUT_SIZE
#undef BUF_SIZE
}; using namespace fastIO;
/*****************************************************/
const int maxn=5e5+4;
int T;
int n,m;ll k;
int a[maxn];
int b[maxn];
int buf[maxn];
inline void merge(int l,int r,int m){
int i=l,j=m+1;
for(int k=l;k<=r;k++){
if(j>r || i<=m &&b[i]<b[j])buf[k]=b[i++];
else buf[k]=b[j++];
}
}
int main(){
read(T);
while(T--){
read(n);read(m);read(k);
FOR(n)read(a[i]);
int l=1,r=l;
int ans=0;
while(l<=n){
ans++;
int p=1;r=l;
ll tmp;
b[l]=a[l];
while(p){
if(r+p>n){p>>=1;continue;}
tmp=0;
for(int i=r+1;i<=r+p;i++){
b[i]=a[i];
}
sort(b+r+1,b+1+r+p);
merge(l,r+p,r); //b[l,r] mer b[r+1,r+p]
//for(int i=l;i<=p+r;i++){
// cout<<buf[i]<<" ";
//}
//cout<<endl;
for(int i=l;i<=l+m-1;i++){
if(i>r+p-i+l)break;
tmp+=sqr(1ll*buf[i]-1ll*buf[r+p-i+l]);
}
//cout<<tmp<<endl;
if(tmp<=k){
for(int i=l;i<=r+p;i++)b[i]=buf[i];
r+=p;p<<=1;
}else{
p>>=1;
}
}
l=r+1;
}
printf("%d\n",ans);
}
}
浙公网安备 33010602011771号