Meaning of the questions:
And m is given undirected edges, each edge has a $ [l, r] $, meaning that the volume of people within this range by this edge, the possibility to ask how many volumes have to make one from 1 to n
Idea: As is undirected edges, 1 and n connectivity can be maintained with disjoint-set.
Consider the most violent approach, each enumerator volume, the volume can be maintained at the current edge with disjoint-set, it is determined to 1 to n connectivity.
Consider optimization, first of all sections must be discrete, and we can be discrete intervals in accordance with the tree line dividing what way, then even look at each sub-section side with the disjoint-set, determine the connectivity, then leave this child when the interval, even the disjoint-set edge operating return on it.
Since each edge is divided up into a log intervals, i.e. are added disjoint-set time log, log open times, the time complexity is (n * logn * logn), wherein a log is brought disjoint-set , the constant is small.
Revocable by rank with disjoint-set to complete the merger, and the back operation only a continuous period of time, there are 2 * n th point discretization, segment tree points Do not open too.
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define pb(x) push_back(x) #define pii pair<int,int > using namespace std; const int maxn=200010; vector<int >tr[maxn<<2]; int n,m; struct edge{ int u,v,l,r; }a[maxn]; int b[maxn<<1],cnt,ans; int fa[maxn],siz[maxn]; int find(int x){ return x==fa[x]?x:find(fa[x]); } void update(int o,int l,int r,int ql,int qr,int i){ if(ql<=l&&r<=qr){ tr[o].pb(i); return; } int mid=(l+r)>>1; if(ql<=mid)update(o<<1,l,mid,ql,qr,i); if(mid<qr)update(o<<1|1,mid+1,r,ql,qr,i); } void dfs(int o,int l,int r){ vector<pii >ve; int si=tr[o].size(); rep(i,0,si-1){ int id=tr[o][i]; int u=a[id].u,v=a[id].v; int fu=find(u),fv=find(v); if(fu==fv)continue; if(siz[fu]>siz[fv])swap(fu,fv); fa[fu]=fv; int d=0; if(siz[fu]==siz[fv])d++; siz[fv]+=d; ve.push_back({fu,d}); } int mid=(l+r)>>1; if(find(1)==find(n)){ ans+=b[r+1]-b[l]; }else if(l<r){ dfs(o<<1,l,mid); dfs(o<<1|1,mid+1,r); } si=ve.size(); dep(i,si-1,0){ siz[fa[ve[i].first]]-=ve[i].second; fa[ve[i].first]=ve[i].first; } } int main(){ cin>>n>>m; rep(i,1,n){ fa[i]=i; siz[i]=1; } for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&a[i].u,&a[i].v,&a[i].l,&a[i].r); b[++cnt]=a[i].l; b[++cnt]=a[i].r+1; } sort(b+1,b+1+cnt); cnt=unique(b+1,b+1+cnt)-b-1; for(int i=1;i<=m;i++){ a[i].l=lower_bound(b+1,b+1+cnt,a[i].l)-b; a[i].r=lower_bound(b+1,b+1+cnt,a[i].r+1)-b; update(1,1,cnt,a[i].l,a[i].r-1,i); } dfs(1,1,cnt); printf("%d\n",ans); }