二分树状数组TLE求助
查看原帖
二分树状数组TLE求助
627293
FanMingxuan楼主2024/3/11 13:40

代码如下


#include<bits/stdc++.h>
using namespace std;
const int N = 100005;
int a[N],b[N];
int n,K;

namespace Array{
	int t[N << 1];
	
	void change(int x,int d){
		while(x < N){
			t[x] += d;
			x += (x & -x);
		}
	}
	
	int query(int x){
		int ans = 0;
		while(x){
			ans += t[x];
			x -= (x & -x);
		}
		return ans;
	}
}

void spread(){
	sort(b + 1,b + n + 1);
	int m = unique(b + 1,b + n + 1) - b - 1;
	for(int i = 1;i <= n;++ i) a[i] = m - (lower_bound(b + 1,b + m + 1,a[i]) - b) + 1;
}

bool check(int t){
	int tot = 1,head = 1,cnt = 0;
	for(int i = 1;i <= n;++ i){
		cnt += Array::query(a[i] - 1);
		if(cnt > t){
			for(int j = head;j < i;++ j) Array::change(a[j],-1);
			head = i;
			cnt = 0;
			tot ++;
			i --;
		}
		else Array::change(a[i],1);
		if(tot > K) return false;
	}
	for(int j = head;j <= n;++ j) Array::change(a[j],-1);
	return true;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int T;
	cin>>T;
	while(T --){
		cin>>n>>K;
		for(int i = 1;i <= n;++ i){
			cin>>a[i];
			b[i] = a[i];
		}
		spread();
		int l = 0,r = n * n + 1;
		while(l < r){
			int mid = (l + r) >> 1;
			if(check(mid)) r = mid;
			else l = mid + 1;
		}
		cout<<l<<"\n";
	}
	return 0;
}

2024/3/11 13:40
加载中...