有个疑问
查看原帖
有个疑问
1417158
_zjzhe楼主2024/12/12 16:09
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,inf=0x3f3f3f3f3f3f3f3fll;
int n,c,f,pre[N],nxt[N];
struct stu{
	int a,b;
	bool operator < (const stu B) const {
		return a < B.a;
	}
}s[N];
struct SGT{
	#define lc (x<<1)
	#define rc (x<<1|1)
	#define mid ((l+r)>>1)
	int val[N<<2],cnt[N<<2];
	void clear(){
		memset(val,0,sizeof(val));
		memset(cnt,0,sizeof(cnt));
	}
	void pushup(int x){
		val[x]=val[lc]+val[rc];
		cnt[x]=cnt[lc]+cnt[rc];
	}
	void upd(int x,int p,int v){
		val[x]+=p;
		cnt[x]+=v;
	}
	void update(int x,int p,int l,int r,int v){
		if(l==r) return upd(x,p,v);
		if(p<=mid) update(lc,p,l,mid,v);
		if(p>mid) update(rc,p,mid+1,r,v);
		pushup(x);
	}
	int query2(int x,int k,int l,int r){
		if(l==r) return l*(k>cnt[x]?cnt[x]:k);
		if(cnt[lc]<k) return val[lc]+query2(rc,k-cnt[lc],mid+1,r);
		else return query2(lc,k,l,mid);
	}
}sg;
signed main(){
	cin>>n>>c>>f;
	for(int i=1;i<=c;i++){
		cin>>s[i].a>>s[i].b;
	}
	sort(s+1,s+1+c);
	for(int i=1;i<=c;i++){
		if(i>(n-1)/2) pre[i]=sg.query2(1,(n-1)/2,0,N);
		else pre[i]=inf;
		sg.update(1,s[i].b,0,N,1);
	}
	sg.clear();
	for(int i=c;i>=1;i--){
		if(i<=c-(n-1)/2) nxt[i]=sg.query2(1,(n-1)/2,0,N);
		else nxt[i]=inf;
		sg.update(1,s[i].b,0,N,1);
		if(pre[i]+s[i].b+nxt[i]<=f) {
			cout<<s[i].a;
			return 0;
		}
	}
	cout<<"-1";
	return 0;
}

第36行,看题解写的都是l*k

if(l==r) return l*k;

如何证明二分出的节点上 cnt[x]>=kcnt[x]>=k 一定成立

2024/12/12 16:09
加载中...