2019 우 객 여름 다 교 훈련소 (제8 차 전) 익스플로러 (선분 수 분해 정 답)
제목:
n 개의 점, m 개의 변 을 제시 하고 각 변 에 범위 가 있 으 며 지정 한 범위 의 숫자 가 통과 할 수 있 습 니 다.지금 1, 1, 1 에 [1, 1 e 9] [1, 1 e9] [1, 1 e9] 가 있 습 니 다. n n 에 도착 하려 면 마지막 에 몇 개의 점 이 도착 할 수 있 는 지 물 어보 세 요.
해석:
직접 뒤 져 서 는 안 될 것 같 습 니 다. 우 리 는 분 치 를 고려 해 보 겠 습 니 다.
분할 구간 [L, R] [L, R] [L, R], 이 구간 을 포함 하 는 모든 변 을 연결 하여 1 → n 1 \ \ to n 1 → n 이 가능 한 지 확인 합 니 다.이것 은 수집 해서 조회 할 수 있다.
가능 하 다 면 [L, R] [L, R] [L, R] 을 설명 하고 답 을 계산 할 수 있 습 니 다.그렇지 않 으 면 우 리 는 [L, m i d], [m i d + 1, R] [L, mid], [mid + 1, R] [L, mid], [mid + 1, R] 을 판단 한다.
tip:
- 그리고 집합 은 거 슬러 올 라 갈 때 뜯 어야 하기 때문에 경로 가 압축 되 지 않 기 때문에 계발 식 합병 이 필요 합 니 다. -우 리 는 모든 변 을 대응 가능 한 집합 ([L, R] [L, R] [L, R] [L, R] [L, R] [L, R] [L, R] [L, R]] [L, R] [L, R] 을 포함 하고, 그 다음 에 [L, m i d] [L, mid] [L, mid] [L, mid]]] - 구간 을 이산 화 할 필요 가 없 기 때문에 구간 값 을 점 에 저장 해 야 한다. 이 체 조 는 R + 1, [g t (L), g e t (R + 1) - 1] R + 1, [get (L), [get (L) - 1) - 1, get (R + 1) - 1] R + 1, [get (L), [get (L), get (R + 1) - 1] - 1] - 1](g e t get 이산 화 i n d e x index index)
코드:
#include
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int maxn=2e5+5;
int n,m;
struct Uni{
int num;
int a[maxn];
void push(int p){
a[++num]=p;
}
void init(){
sort(a+1,a+1+num);
num=unique(a+1,a+1+num)-a-1;
}
int pos(int val){
return lower_bound(a+1,a+1+num,val)-a;
}
}U;
struct edge{
int l,r,u,v;
}e[maxn];
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid (l+r>>1)
vector<int>tr[maxn<<2];
void insert(int rt,int l,int r,int L,int R,int id){
if(l>=L&&r<=R){
tr[rt].push_back(id);
return ;
}
if(L<=mid)
insert(ls,l,mid,L,R,id);
if(R>mid)
insert(rs,mid+1,r,L,R,id);
}
#define pill pair
namespace link{
int fa[maxn];
int siz[maxn];
void init(int n){
rep(i,1,n)fa[i]=i,siz[i]=1;
}
int fin(int a){
return fa[a]==a?a:fin(fa[a]);
}
stack<pill>sta;
bool un(int a,int b){
int f1=fin(a),f2=fin(b);
if(f1==f2)return 0;
if(siz[f1]>siz[f2])swap(f1,f2);
fa[f1]=f2;
sta.push({f1,f2});
siz[f2]+=siz[f1];
return 1;
}
void undo(int tim){
while(tim--){
auto p=sta.top();sta.pop();
siz[p.second]-=siz[p.first];
fa[p.first]=p.first;
}
}
}
using namespace link;
int ans;
void query(int rt,int l,int r){ //
int ct=0;
for(auto i:tr[rt]){
int u=e[i].u,v=e[i].v;
un(u,v)&&++ct;
}
if(fin(1)==fin(n)){
ans+=U.a[r+1]-U.a[l];
}
else if(l==r){
;
}
else{
query(ls,l,mid);
query(rs,mid+1,r);
}
undo(ct);
}
int main(){
scanf("%d%d",&n,&m);
U.num=0;
rep(i,1,m){
scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].l,&e[i].r);
U.push(e[i].l);
U.push(e[i].r+1);
}
U.init();
rep(i,1,m){
e[i].l=U.pos(e[i].l);
e[i].r=U.pos(e[i].r+1)-1;
insert(1,1,U.num,e[i].l,e[i].r,i);
}
init(n);
query(1,1,U.num);
printf("%d
",ans);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
2019 우 객 여름 다 교 훈련소 (제8 차 전) 익스플로러 (선분 수 분해 정 답)n 개의 점, m 개의 변 을 제시 하고 각 변 에 범위 가 있 으 며 지정 한 범위 의 숫자 가 통과 할 수 있 습 니 다.지금 1, 1, 1 에 [1, 1 e 9] [1, 1 e9] [1, 1 e9] 가 있 습 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.