求调 && 玄关
查看原帖
求调 && 玄关
555617
Targanzqq楼主2025/2/3 16:32
#include<bits/stdc++.h>
#define int long long
#define N 100005
#define mp make_pair
#define fi first
#define se second
using namespace std;

int n,m,q,ix[N],id[N];
map<int,int> g[N];
vector<int> gd[N],ik;
multiset<int> t[3][3];
multiset<int> in[N][3];
multiset<int> e[N][3];

signed main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		//if(!g[u][v]){
			g[u][v]=w;
			g[v][u]=w;
		    t[0][0].insert(w);
	    //}
	}
	int lim=sqrt(m);
	for(int i=1;i<=n;i++){
		if(g[i].size()>lim){
			id[i]=1;ik.push_back(i);
		}
	}
	for(int i=1;i<=n;i++){
		if(id[i]){
			for(auto k:g[i]){
				int j=k.fi,v=k.se;
				t[0][0].erase(t[0][0].find(v));
				in[i][0].insert(j);
				e[i][0].insert(v);
				if(id[j])gd[i].push_back(j);
			}
		}
	}
	cin>>q;
    for(int x=1;x<=q;x++){
    	string s;int i;
    	cin>>s;
    	if(s[0]=='M'){
    		cin>>i;int to=s[4]-'A';
    		if(!id[i]){
    			for(auto k:g[i]){
    				int j=k.fi,v=k.se;
    				if(id[j]){
    					in[j][ix[i]].erase(in[j][ix[i]].find(i));
    					e[j][ix[i]].erase(e[j][ix[i]].find(v));
    					in[j][to].insert(i);
    					e[j][to].insert(v);
					}
    				if(!id[j]){
	    				int l1=min(ix[i],ix[j]),l2=max(ix[i],ix[j]);
	    				int l3=min(to,ix[j]),l4=max(to,ix[j]);
	    				t[l1][l2].erase(t[l1][l2].find(v));
						t[l3][l4].insert(v);
				    }
				}
			}
			if(id[i]){
				for(auto j:gd[i]){
					if(!id[j])continue;
					in[j][ix[i]].erase(in[j][ix[i]].find(i));
    				e[j][ix[i]].erase(e[j][ix[i]].find(g[i][j]));
    				in[j][to].insert(i);
    				e[j][to].insert(g[i][j]);
				}
			}
			ix[i]=to;
	    }
	    if(s[0]=='A'){
	    	int p1=s[3]-'A',p2=s[4]-'A',ans=1145141919810;
	    	if(t[p1][p2].size())ans=*t[p1][p2].begin();
	    	for(auto i:ik){
	    		if(ix[i]!=p1)continue;
	    		if(e[i][p2].size())ans=min(ans,*e[i][p2].begin());
			}
			for(auto i:ik){
	    		if(ix[i]!=p2)continue;
	    		if(e[i][p1].size())ans=min(ans,*e[i][p1].begin());
			}
			if(ans==1145141919810)cout<<"No Found!";
			else cout<<ans;
			cout<<"\n";
		}
	}
}
/*
设立一个阈值lim
如果这个点相连的边数小于B就直接暴力转换集合,时间复杂度O(qB)
如果相连的边数大于B,这样的点只有最多n/B个
我们可以维护大点连的点
如果这些点中的某个点改动了,那我们只要在其他大点中把这个点的颜色修改即可
这部分的时间复杂度O(qn/Blogn)
对于查询,我们可以用 $set$ 维护6种情况的边权,支持删除
然后我们维护关键点的 $set$,然后再维护一个边权的 $set$
然后再维护一个查找边权的 $map$,这样就可以在修改点的时候把边权带走
这样的时间复杂度也是O(qn/Blogn)
我们合并一下,就是B=sqrt(nlogn)
这样时间复杂度就是 $nsqrt(nlogn)) 
可能是常数问题,那样会T,改一下lim就不T了,但是WA
*/
2025/2/3 16:32
加载中...