时间复杂度问题悬关
查看原帖
时间复杂度问题悬关
185322
cmDeltaT楼主2024/11/18 16:57

如题,下述代码中需要完全遍历线段树,估测时间复杂度为 O(nmlogm)O(nm\log m) ,但实际得分 9595 ,且除 #18 其它点最多只有 132 ms132\ \text{ms} ,请求解答分析实际时间复杂度。

#include<bits/stdc++.h>
using namespace std;

using ll=long long;
constexpr ll N=200005,INF=2e9+7;

struct prt {
	ll s,t,id;
	bool operator<(const prt&b)const {
		return t<b.t;
	}
} p[N];

ll n,m;
vector<ll> ans[N];

struct sta {
	ll fl,v,p;
};

sta merge(const sta&a,const sta&b) {
	sta res;
	if(a.v<=b.v) res=sta({0,a.v,a.p});
	else res=sta({0,b.v,b.p});
	res.fl=a.fl&&b.fl;
	return res;
}

struct node {
	ll l,r,tS;
	sta s;
} tr[N*4];

void build(ll x,ll l,ll r) {
	tr[x]=node({l,r,0,sta({1,0,l})});
	if(l==r) return;
	ll mid=(l+r)>>1;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r);
	tr[x].s=merge(tr[x*2].s,tr[x*2+1].s);
}

void msub(ll x,ll v) {
	if(tr[x].s.fl==1) return;
	if(tr[x].s.v>=v) {
		tr[x].s.v-=v;
		tr[x].tS+=v;
		return;
	}
	if(tr[x].l==tr[x].r) {
		tr[x].s=sta({0,max(tr[x].s.v-v,0ll),tr[x].l});
		if(tr[x].s.v==0) tr[x].s.fl=1;
		return;
	}
	msub(x*2,v+tr[x].tS);
	msub(x*2+1,v+tr[x].tS);
	tr[x].tS=0;
	tr[x].s=merge(tr[x*2].s,tr[x*2+1].s);
}

void madd(ll x,ll p,ll v) {
	if(tr[x].l==tr[x].r) {
		tr[x].s.v+=v;
		tr[x].s.fl=0;
		return;
	}
	if(tr[x].tS!=0) {
		msub(x*2,tr[x].tS);
		msub(x*2+1,tr[x].tS);
		tr[x].tS=0;
	}
	if(p<=tr[x*2].r) madd(x*2,p,v);
	else madd(x*2+1,p,v);
	tr[x].s=merge(tr[x*2].s,tr[x*2+1].s);
}

sta qpos(ll x,ll l,ll r) {
	if(l>tr[x].r||tr[x].l>r) return sta({0,INF,N+1});
	if(l<=tr[x].l&&tr[x].r<=r) return tr[x].s;
	if(tr[x].tS!=0) {
		msub(x*2,tr[x].tS);
		msub(x*2+1,tr[x].tS);
		tr[x].tS=0;
	}
	return merge(qpos(x*2,l,r),qpos(x*2+1,l,r));
}

ll read() {
	ll x=0,f=1;
	char ch=0;
	while(ch<'0'||ch>'9') {
		ch=getchar();
		if(ch=='-') f=-1;
	}
	while(ch>='0'&&ch<='9') {
		x=x*10+(ch-'0');
		ch=getchar();
	}
	return x*f;
}

void write(ll x) {
	static ll S[35];
	ll top=0;
	do {
		S[top++]=x%10;
		x/=10;
	} while(x);
	if(!top) putchar('0');
	while(top) putchar(S[--top]+'0');
}

int main() {
	n=read();
	m=read();
	for(ll i=1; i<=n; ++i) {
		p[i].s=read();
		p[i].t=read();
		p[i].id=i;
	}
	sort(p+1,p+1+n);
	build(1,1,m);
	for(ll i=1,pr=0; i<=n; ++i) {
		msub(1,p[i].t-pr);
		pr=p[i].t;
		ll pos=qpos(1,1,m).p;
		ans[pos].push_back(p[i].id);
		madd(1,pos,p[i].s);
	}
	for(ll i=1; i<=m; ++i) {
		sort(ans[i].begin(),ans[i].end());
		write(ans[i].size());
		for(ll x:ans[i]) {
			putchar(' ');
			write(x);
		}
		putchar('\n');
	}
	return 0;
}

2024/11/18 16:57
加载中...