[CF2157E] Adjusting Drones 题解
aeiouaoeiu · · 题解
首先
观察一次操作时
这样就很像一个技巧型 dp 了,但是这里介绍一个力大砖飞做法。
首先
进行操作后
若要检查
时间复杂度
::::info[code]
#include<bits/stdc++.h>
#define pb emplace_back
#define pob pop_back
#define mp make_pair
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const ll maxn=1000007,ee=1e18;
ll n,k,a[maxn],b[maxn],f[maxn],ans;
struct Dsu{
ll fa[maxn],siz[maxn],l[maxn],r[maxn];
void init(ll n){
iota(fa+1,fa+1+n,1),fill(siz+1,siz+1+n,1);
iota(l+1,l+1+n,1),iota(r+1,r+1+n,1);
}
ll fid(ll x){for(;x!=fa[x];x=fa[x]=fa[fa[x]]); return x;}
void merge(ll x,ll y){
ll fx=fid(x),fy=fid(y);
if(fx==fy) return;
if(siz[fx]>siz[fy]) swap(fx,fy);
siz[fy]+=siz[fx];
l[fy]=min(l[fy],l[fx]),r[fy]=max(r[fy],r[fx]);
fa[fx]=fy;
}
}dsu;
bool check(ll x){
dsu.init(4*n);
for(ll i=2*n,cur,p,to;i>=1;i--){
cur=b[i],p=i;
for(ll j=0;;){
if(cur<=1) break;
dsu.merge(p,p+1);
to=dsu.r[dsu.fid(p)];
j+=to-p,p=to;
if(j>x) break;
cur--;
}
if(b[i]) dsu.merge(p,p+1);
if(cur>k) return 0;
}
return 1;
}
ll solve(void){
for(ll l=0,r=3*n,mid;l<=r;){
mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}
int main(void){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
ll T=1; cin>>T;
for(;T--;){
cin>>n>>k,ans=0;
for(ll i=1;i<=2*n;i++) b[i]=0;
for(ll i=1;i<=n;i++) cin>>a[i],b[a[i]]++;
cout<<solve()<<"\n";
}
return 0;
}
::::