P14507 缺零分治 mexdnc题解

P14507 缺零分治 mexdnc

考时思路对了,但是代码太乱了,冗长复杂,难以调试,我直接放弃了,赛后补题,看题解,发现写的都是gousi(个人感觉,我确实看不懂写的都是啥,当然我写的体积也不是让别人看的题解),看部分题解发现我的思路确实没问题,于是重写了一遍赛时的思路,稍微调了调就过了。

肯定把能得到的mex都提出来,每次肯定先用大的mex,然后依次用,发现可以前缀和优化后,直接二分查找,然后再将剩余减去即可。

#include<bits/stdc++.h>
#define ll long long
#define int ll
#define ls p<<1
#define rs p<<1|1
#define re register 
#define pb push_back
#define pir pair<int,int> 
#define f(a,x,i) for(int i=a;i<=x;i++)
#define fr(a,x,i) for(int i=a;i>=x;i--)
#define lowbit(x) (x&-x)
using namespace std;
const int N=2e5+10;
const int M=5e6+10;
const int mod=1e18+2;
const int INF=1e9+7;
mt19937 rnd(251);

int n,q;
map<int,int> mp;
map<int,int> sum;
int f[N];

bool cmp(int x,int y){
	return x>y;
}


int a[N],b[N];
int c[N];
int cnt=0;

int query(int x){
	int pos=upper_bound(a+1,a+1+cnt,x)-a;
	
	int ans=b[pos-1];
	int k=x-a[pos-1];
	if(k){
		if(pos>cnt){
			ans=-1;
		}
		else{
			if(k<c[pos]){
				ans+=1+(pos==1);
			}
			else{
				ans+=k/c[pos]+((k%c[pos])!=0);
			}
		}
	}

	return ans;	
}

void solve(){
	cin>>n>>q;
	
	for(int i=1;i<=n;i++){
		int x,y;
		cin>>x>>y;
		mp[x]+=y;
		if(x>n){
			continue;
		}
		f[x]+=y;
	}
	
//	for(int i=0;i<=n;i++){
//		cout<<f[i]<<" ";
//	}
//	cout<<"\n";
	
	int mx=0;
	for(int i=1;i<=n+1;i++){
		f[i]=min(f[i-1],f[i]);
		if(f[i]!=0){
			mx=max(mx,i+1);
			
			if(mp[i]<mp[i-1]){
				c[++cnt]=i;
				sum[i]=mp[i-1]-mp[i];
			}
			else{
				mp[i]=mp[i-1];
			}
		}
		else{
			c[++cnt]=i;
			sum[i]=mp[i-1]-mp[i];
			break;
		}
	}
	
	sort(c+1,c+1+cnt,cmp);
	
	for(int i=1;i<=cnt;i++){
		if(a[i-1]>mod){
			a[i]=a[i-1];
			b[i]=b[i-1];	
		}
		else{
			a[i]=a[i-1]+c[i]*sum[c[i]];
			b[i]=b[i-1]+sum[c[i]];
		}
	}
	
//	for(int i=1;i<=cnt;i++){
//		cout<<c[i]<<" "<<sum[c[i]]<<"\n";
//	}
//	cout<<"\n";
	
	
	for(int i=1;i<=q;i++){
		int x;
		cin>>x;
		if(f[0]==0){
			if(x!=0){
				cout<<"-1\n";
				continue;	
			} 
			else{
				cout<<"1\n";
				continue;
			}
		}
		else{
			if(x==0){
				cout<<"-1\n";
				continue;	
			}
		}
		if(mx==x){
			cout<<"1\n";
			continue;
		}
		cout<<query(x)<<"\n";
	}
}

void clear(){
	mp.clear();
	sum.clear();
	for(int i=0;i<=n+3;i++){
		f[i]=a[i]=b[i]=c[i]=0;
	}
	cnt=0;
}

signed main(){
//  	freopen("mexdnc2.in","r",stdin);
//  	freopen("a.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    int t;
	cin>>t;
	while(t--){
		solve();
		clear();
	} 
    return 0;
}
posted @ 2025-11-16 20:12  sad_lin  阅读(6)  评论(0)    收藏  举报