zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第八场)E.Explorer

    链接:https://ac.nowcoder.com/acm/contest/888/E
    来源:牛客网

    Gromah and LZR have entered the fifth level. Unlike the first four levels, they should do some moves in this level.

    There are nn_{}n vertices and mm_{}m bidirectional roads in this level, each road is in format (u,v,l,r)(u, v, l, r)_{}(u,v,l,r), which means that vertex uu_{}u and vv_{}v are connected by this road, but the sizes of passers should be in interval [l,r][l, r]_{}[l,r]. Since passers with small size are likely to be attacked by other animals and passers with large size may be blocked by some narrow roads.

    Moreover, vertex 11_{}1 is the starting point and vertex nn_{}n is the destination. Gromah and LZR should go from vertex 11_{}1 to vertex nn_{}n to enter the next level.

    At the beginning of their exploration, they may drink a magic potion to set their sizes to a fixed positive integer. They want to know the number of positive integer sizes that make it possible for them to go from 11_{}1 to nn_{}n.

    Please help them to find the number of valid sizes.

    输入描述:

    The first line contains two positive integers n,mn,m_{}n,m, denoting the number of vertices and roads.
     
    Following m lines each contains four positive integers u,v,l,ru, v, l, r_{}u,v,l,r, denoting a bidirectional road (u,v,l,r)(u, v, l, r)_{}(u,v,l,r).
     
     
    1≤n,m≤105,1≤u<v≤n,1≤l≤r≤1091 le n,m le 10^5, 1 le u < v le n, 1 le l le r le 10^91n,m105,1u<vn,1lr109

    输出描述:

    Print a non-negative integer in a single line, denoting the number of valid sizes.
    示例1

    输入

    5 5
    1 2 1 4
    2 3 1 2
    3 5 2 4
    2 4 1 3
    4 5 3 4

    输出

    2

    题意:
    给定m条边,每条边有一个通过的阈值,问可以从1到n的值有多少个.
    思路:
    把这些边放入一个点表示区间的线段树里面.
    这真是我从未见过的全新套路,在线段树上dfs,相当于枚举权值,由于每一个点代表区间,所以每次就枚举到了一个区间.

    枚举之时用并查集判断.
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    
    #define fuck(x) cerr<<#x<<" = "<<x<<endl;
    #define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
    #define lson l,mid,ls
    #define rson mid+1,r,rs
    #define ls (rt<<1)
    #define rs ((rt<<1)|1)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int loveisblue = 486;
    const int maxn = 100086;
    const int maxm = 100086;
    const int inf = 0x3f3f3f3f;
    const ll Inf = 999999999999999999;
    const int mod = 1000000007;
    const double eps = 1e-6;
    const double pi = acos(-1);
    int n,m;
    struct edge{
        int u,v,l,r;
    }e[maxn];
    int f[maxn],rk[maxn];
    int rem[maxn],tot;
    
    vector<int>eg[maxn<<2];
    
    void update(int l,int r,int rt,int L,int R,int id){
        if(rt==0){ return;}
        if(L<=l&&R>=r){
            eg[rt].push_back(id);
            return;
        }
        int mid = (l+r)>>1;
        if(L<=mid)update(l,mid,rt*2,L,R,id);
        if(R>mid)update(mid+1,r,rt*2+1,L,R,id);
    }
    
    int getf(int x){
        if(x==f[x]){ return x;}
        return getf(f[x]);
    }
    
    int ans = 0;
    struct node{
        int num,type;
    };
    
    void dfs(int l,int r,int rt){
    
        stack<node>tmp;
        for(auto it:eg[rt]){
            int t1 = getf(e[it].u);
            int t2 = getf(e[it].v);
            if(rk[t1]<rk[t2]){
                tmp.push(node{f[t1],1});
                f[t1]=f[t2];
            }else if(rk[t1]>rk[t2]){
                tmp.push(node{f[t2],1});
                f[t2]=f[t1];
            }else{
                tmp.push(node{f[t2],2});
                f[t2]=f[t1];
                rk[t2]++;
            }
        }
        
        if(l==r){
            if(getf(1)==getf(n)&&l!=tot){
                ans+=rem[r+1]-rem[l];
            }
            while (!tmp.empty()){
                node it = tmp.top();
                tmp.pop();
                f[it.num]=it.num;
                if(it.type==2){
                    rk[it.num]--;
                }
            }
            return;
        }
        int mid = (l+r)>>1;
        dfs(lson);
        dfs(rson);
        while (!tmp.empty()){
            node it = tmp.top();
            tmp.pop();
            f[it.num]=it.num;
            if(it.type==2){
                rk[it.num]--;
            }
        }
    }
    
    int get_id(int x){
        return lower_bound(rem+1,rem+1+tot,x)-rem;
    }
    
    int main() {
    
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++){
            f[i]=i;
            rk[i]=1;
        }
    
        for(int i=1;i<=m;i++){
            scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].l,&e[i].r);
            rem[++tot] = e[i].l;
            rem[++tot] = e[i].r+1;
        }
        sort(rem+1,rem+1+tot);
        tot = unique(rem+1,rem+1+tot)-rem-1;
    
        for(int i=1;i<=m;i++){
            cout<<get_id(e[i].l)<<" "<<get_id(e[i].r+1)-1<<endl;
            update(1,tot,1,get_id(e[i].l),get_id(e[i].r+1)-1,i);
        }
        dfs(1,tot,1);
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Vim学习指南
    frambuffer lcd.c
    工控显示界面
    ubuntu nfs 开发板
    java初学1
    使用多态来实现数据库之间的切换
    Space Shooter 太空射击
    CandyCrush 糖果传奇
    进制转换以及原码、反码、补码
    winform小知识
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/11344044.html
Copyright © 2011-2022 走看看