QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#643540#6520. Classic ProblemEdward2019TL 0ms20028kbC++232.6kb2024-10-15 21:40:472024-10-15 21:40:47

Judging History

你现在查看的是最新测评结果

  • [2024-10-15 21:40:47]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:20028kb
  • [2024-10-15 21:40:47]
  • 提交

answer

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,bas=19260817,inf=1e18;
int n,m,u[N],v[N],w[N],cnt,to[N],ans,rz,pre[N],suf[N],f[N],siz[N];
pair<int,int>sb[N];
map<int,int>mp;
unordered_map<int,bool>g;
struct node{int typ,l,r;};
vector<node>vec;
inline int find(int x){return (x==f[x])?x:(f[x]=find(f[x]));}
inline bool merge(int x,int y){
	x=find(x),y=find(y);
	if(siz[x]>siz[y])swap(x,y);
	return ((x==y)?0:((f[x]=y,siz[y]+=siz[x]),1));
}
inline int get(int x){ 
	int l=1,r=rz;
	while(l<r){
		int mid=(l+r+1)>>1;
		if(vec[mid].l>x)r=mid-1;
		else l=mid;
	}
	return l;
}
signed main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int T;
	cin>>T;
	while(T--){
		cin>>n>>m,mp.clear(),g.clear(),vec.clear(),ans=0;
		if(!m){cout<<n-1<<"\n";continue;}
		for(int i=1;i<=m;i++)cin>>u[i]>>v[i]>>w[i],mp[u[i]]=mp[v[i]]=1;
		cnt=0;
		for(auto &x:mp)x.second=++cnt,to[cnt]=x.first;
		to[++cnt]=n+1;
		for(int i=1;i<=m;i++)u[i]=mp[u[i]],v[i]=mp[v[i]],g[u[i]*bas+v[i]]=g[v[i]*bas+u[i]]=1;
		vec.push_back({0,0,0});
		if(to[1]>1)vec.push_back({0,1,to[1]-1}),ans+=to[1]-2;
		for(int i=1;i<cnt;i++){
			vec.push_back({1,to[i],to[i]});
			if(to[i]<to[i+1]-1)vec.push_back({0,to[i]+1,to[i+1]-1}),ans+=to[i+1]-to[i]-2;
		}
		rz=vec.size()-1;
		for(int i=1;i<=rz;i++)f[i]=i,siz[i]=1;
		for(int i=1;i<=m;i++)u[i]=get(to[u[i]]),v[i]=get(to[v[i]]);
		while(1){
			if(siz[find(1)]==rz)break;
			for(int i=1;i<=m;i++)u[i]=find(u[i]),v[i]=find(v[i]);
			for(int i=1;i<=rz;i++)sb[i]=make_pair(inf,0),pre[i]=suf[i]=0;
			for(int i=2;i<=rz;i++)pre[i]=((find(i)==find(i-1))?pre[i-1]:vec[i-1].r);
			for(int i=rz-1;i;i--)suf[i]=((find(i)==find(i+1))?suf[i+1]:vec[i+1].l);
			for(int i=1;i<=m;i++)
				if(u[i]^v[i])sb[u[i]]=min(sb[u[i]],make_pair(w[i],v[i])),sb[v[i]]=min(sb[v[i]],make_pair(w[i],u[i]));
			for(int i=1;i<=rz;i++){
				if(!pre[i])continue;
				int u=pre[i];
				while(u&&g[vec[i].l*bas+u]){
					u--;
					int sb=get(u);
					if(find(sb)==find(i))u=pre[vec[sb].l];
				}
				if(!u)continue;
				int fu=find(get(u)),w=vec[i].l-u;
				sb[fu]=min(sb[fu],make_pair(w,find(i))),sb[find(i)]=min(sb[find(i)],make_pair(w,fu));
			}
			for(int i=rz;i;i--){
				if(!suf[i])continue;
				int u=suf[i];
				while((u<=n)&&u&&g[vec[i].r*bas+u]){
					u++;
					int sb=get(u);
					if(find(sb)==find(i))u=suf[vec[sb].r];
				}
				if((!u)||(u>n))continue;
				int fu=find(get(u)),w=u-vec[i].r;
				sb[fu]=min(sb[fu],make_pair(w,i)),sb[find(i)]=min(sb[find(i)],make_pair(w,fu));
			}
			for(int i=1;i<=rz;i++)
				if(sb[i].first^inf)ans+=sb[i].first*merge(i,sb[i].second);
		}
		cout<<ans<<"\n";
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 20028kb

input:

3
5 3
1 2 5
2 3 4
1 5 0
5 0
5 4
1 2 1000000000
1 3 1000000000
1 4 1000000000
1 5 1000000000

output:

4
4
1000000003

result:

ok 3 number(s): "4 4 1000000003"

Test #2:

score: -100
Time Limit Exceeded

input:

16
1000000000 0
447 99681
1 2 1000000000
1 3 1000000000
2 3 1000000000
1 4 1000000000
2 4 1000000000
3 4 1000000000
1 5 1000000000
2 5 1000000000
3 5 1000000000
4 5 1000000000
1 6 1000000000
2 6 1000000000
3 6 1000000000
4 6 1000000000
5 6 1000000000
1 7 1000000000
2 7 1000000000
3 7 1000000000
4 7 ...

output:


result: