倍增 质检习题
/* 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; }