E. Spanning Tree Queries
纯暴力做法t了 我们考虑如何优化
我们可以发现要是所有绝对值曲线单调性不变 我们MST的答案是可以O(1)转移的 res+=(x-prex)*(num1-num2)
单调性改变的点 会有e1,e2交点 e1与x轴交点 再对每一个交点跑一边Kruscal O(m^3 logm)
最后要注意的是 我们应该将0入队 让他无论如何都先跑一边Kruscal 不然我们的prex没有初始化
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define Endl '\n'
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int p[55];
int find(int x){
if(p[x]!=x)p[x]=find(p[x]);
return p[x];
}
void merge(int x, int y){
p[find(x)] = find(y);
}
void solve() {
int n,m;cin>>n>>m;
array<int,3>e[m];
for(int i=0;i<m;i++){
int s,t,w;cin>>s>>t>>w;
e[i]={w,s,t};
}
set<int>s;
for(int i=0;i<m;i++)for(int j=i+1;j<m;j++)
s.insert((e[i][0]+e[j][0])/2+1);
for(int i=0;i<m;i++)s.insert(e[i][0]);
int P,k,a,b,c;cin>>P>>k>>a>>b>>c;
vector<int>query(k);
for(int i=0;i<P;i++){
cin>>query[i];
}
for(int i=P;i<k;i++){
int t=(query[i-1]*a+b)%c;
query[i]=t;
}
sort(query.begin(),query.end());
s.insert(0);
int num1=0,num2=0,ans=0,cost=0,prex=-inf;
for(auto x:query){
if(!s.empty()&&*s.begin()<=x){
while(!s.empty()&&*s.begin()<=x)s.erase(s.begin());
sort(e,e+m,[&](auto e1,auto e2){return abs(e1[0]-x)<abs(e2[0]-x);});
cost=num1=num2=0;
int tmp=0;
for(int i=1;i<=n;i++)p[i]=i;
for(auto [w,s,t]:e){
if(tmp==n-1)break;
if(find(s)!=find(t)){
tmp++;
merge(s,t);
if(w<=x)num1++;
else num2++;
cost+=abs(w-x);
}
}
}else cost+=(x-prex)*(num1-num2);
ans^=cost;
prex=x;
}
cout<<ans<<endl;
}
signed main(){
fast
int T;T=1;
while(T--) {
solve();
}
return ~~(0^_^0);
}
标签:Educational,const,int,Codeforces,122,交点,define
From: https://www.cnblogs.com/ycllz/p/16656096.html