标签:排序 合并 optimize space reg ++ its 有序 for
这题大概就是说给定一个长为n的序列p,将p分为若干段,使得每段取出m对数,令sum=\(\sum\) 每对数差的平方,在是sum尽量大的条件下,使sum不大于常数k。共T组数据。
对于 100%的数据,\(T\le 12\),\(1\le n,m\le 5\cdot 10^5\),\(0\le k\le 10^{18}\),\(0\le Pi\le 2^{20}\) 。时限1s
样例输入
2
5 1 49
8 2 1 7 9
5 1 64
8 2 1 7 9
样例输出
2
1
这题据说原题时限3s,结果xj搞成1s,然后卡掉了一种算法(好像是std,包括老师说的正解);
思路1(就是被卡掉的):对于每一个左端点,二分右端点(或者倍增上去),暴力sort一下区间,找到最大的满足条件的位置,时间复杂度 \(O(n \log ^2n)\)
#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
const int N=500005;
int T,n,m,ans;
ll p[N],k,tmp[N];
inline bool pd(int l,int r)
{
ll sum=0;
for(register int i=l;i<=r;++i)
tmp[i]=p[i];
sort(tmp+l,tmp+r+1);
int mx=min(m,(r-l+1)>>1);
for(register int i=1;i<=mx;++i)
sum+=(tmp[l+i-1]-tmp[r-i+1])*(tmp[l+i-1]-tmp[r-i+1]);
return sum<=k;
}
int main()
{
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%d%d%lld",&n,&m,&k);
for(register int i=1;i<=n;++i)
scanf("%lld",&p[i]);
int l=1,r,q;
while(l<=n)
{
r=l;q=1;
while(q)
{
if(r+q<=n&&pd(l,r+q))r+=q,q<<=2;
else q>>=1;
}
l=r+1;
++ans;
}
printf("%d\n",ans);
}
return 0;
}
上面那份80pts,卡个常就90了
思路2:每次暴力排序浪费时间,考虑类似归并排序合并2个有序序列。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=500005;
int T,n,m,ans;
ll p[N],k,a[N],b[N];
inline void msort(int l,int r,int mid) {
int x=l,y=l,z=mid+1;
while(x<=mid&&z<=r) {
if(a[x]<a[z])b[y++]=a[x++];
else b[y++]=a[z++];
}
while(x<=mid)b[y++]=a[x++];
while(z<=r)b[y++]=a[z++];
}
inline bool pd(int l,int r,int mid) {
for(register int i=mid+1;i<=r;++i)a[i]=p[i];
sort(a+mid+1,a+r+1);
msort(l,r,mid);
ll sum=0;
int num=1,lt=l,rt=r;
while(lt<rt&&num<=m) {
++num;
ll tmp=b[lt++]-b[rt--];
sum+=tmp*tmp;
}
return sum<=k;
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d%d%lld",&n,&m,&k);
for(register int i=1; i<=n; ++i)
scanf("%lld",&p[i]);
int l=1,r=1,q=1;ans=0;
a[1]=p[1];
while(l<=n) {
while(q) {
if(r+q<=n&&pd(l,r+q,r)) {
r+=q,q<<=1;
for(int i=l; i<=r; ++i)
a[i]=b[i];
}
else q>>=1;
}
l=r+1,r=l,++ans,q=1;
}
printf("%d\n",ans);
}
return 0;
}
标签:排序 合并 optimize space reg ++ its 有序 for
原文地址:https://www.cnblogs.com/zzctommy/p/12341650.html