整体二分 TLE80 求调
查看原帖
整体二分 TLE80 求调
757101
junee楼主2024/8/23 22:51

为什么别人的跑的飞起,我 T 的飞起:(。

#include<iostream>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<random>
#include<chrono>
#include<vector>
using namespace std;
mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());
typedef long long LL;
const int N=2e5+10;
vector<int>nums;
int n,T;
int ans[N];
struct query{
	int l,r,k,id;
}q[N*2],q1[N*2],q2[N*2];
int tt=0;
int find(int x){
	return lower_bound(nums.begin(),nums.end(),x)-nums.begin();
}
int tr[N];
void add(int x,int k){
	for(;x<=n;x+=x&-x)tr[x]+=k;
}
int ask(int x){
	int res=0;
	for(;x;x-=x&-x)res+=tr[x];
	return res;
}
void solve(int l,int r,int L,int R){
	if(l>r)return;
	if(L==R){
		for(int i=l;i<=r;i++)
			if(q[i].id)ans[q[i].id]=L;
		return;
	}
	int mid=(L+R)>>1,l1=0,l2=0;
	for(int i=l;i<=r;i++){
		if(!q[i].id){
			if(find(q[i].k)<=mid){
				add(q[i].l,1);
				q1[++l1]=q[i];
			}
			else q2[++l2]=q[i];
		}
		else{
			int Q=ask(q[i].r)-ask(q[i].l-1);
			if(Q>=q[i].k)q1[++l1]=q[i];
			else q2[++l2]=q[i],q2[l2].k-=Q;
		}
	}
	for(int i=1;i<=l1;i++){
		if(!q1[i].id)add(q1[i].l,-1);
	}		
	for(int i=l,j=1;i<=l+l1-1;i++,j++)q[i]=q1[j];
	for(int i=l+l1,j=1;i<=r;i++,j++)q[i]=q2[j];
	solve(l,l+l1-1,L,mid);
	solve(l+l1,r,mid+1,r);
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n>>T;
	for(int i=1,x;i<=n;i++){
		cin>>x;
		nums.push_back(x);
		q[++tt]={i,0,x,0};
	}
	for(int i=1;i<=T;i++){
		int l,r,k;
		cin>>l>>r>>k;
		q[++tt]={l,r,k,i};
	}
	sort(nums.begin(),nums.end());
	nums.erase(unique(nums.begin(),nums.end()),nums.end());
	solve(1,tt,0,nums.size());
	for(int i=1;i<=T;i++)cout<<nums[ans[i]]<<'\n';
	return 0;
}
2024/8/23 22:51
加载中...