zoukankan      html  css  js  c++  java
  • 《HDU 6218》

    真的波折。一开始半小时出来一个思路,写了半天的树套树,但是发现题目理解错了。

    这题的桥意思是对于当前的图来说,删去这条边是否可以造成两个点不连通(也就是说图可能是不连通的)。

    其实这样的情况和我一开始分析的思路也差不多。

    我们以竖边来隔开各个部分,可以发现,只有在环上的边删去才不是桥。

    那么我们就可以维护环上的边的条数来计算。

    这里我们还要分析一些东西:

    1:这个横边必须要满足上下两条都有,如果上下某条没有那么,那么它肯定无法组成环。

    也就是说我们维护的横边都是上下都有的那种。

    2:我们不需要一条条维护,我们直接维护整条连续的横边,因为他们被包含在同一个环中肯定有同一性质。

    所以我们需要去找到这个连续横边内部的最左的竖边,和最右的竖边。那么这两条竖边和中间的横边组成的就是这段横边能组成的最大环。

    有了这两点,我们就需要去维护了,首先,很明显我们可以用线段树去维护竖边(我一开始写的树套树也是这样..)

    对于横边,我们可以用set去维护一整段,然后加点和拆点的时候,暴力拆除。因为我们每次操作都是单点的,所以每次的复杂度只有logn。

    这里加点和删点都有几种情况,分析一下即可。

    这里set有很多的问题:

    因为对于多键值的情况,set对于第一关键字相等的情况也看做相同。

    所以,因为左界可能存在重复次数,所以要用multiset。而且因为这里是迭代器的指针,在我们对set操作之后再去指针指向原地址,里面的数据可能已经变换了。

    所以我们每次应该先计算cal再去操作set,并且我们尽量去删L,r而不是重新构建Line{L->L,L->r}这种再去删除,因为它再次去检索可能会导致删除的不是我们想要的。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> pii;
    #define rg register
    const int N = 1e6 + 5;
    const int M = 2e4 + 5;
    const double eps = 1e-10;
    const LL Mod = 1e9 + 7;
    #define pi acos(-1)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline int read() {
        rg int f = 1,x = 0;rg char c = getchar();
        while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
    inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
    inline long long MUL(long long x,long long y) {return x * y % Mod;}
    
    struct Line{
        int L,r;
        bool operator < (const Line &a)const{
            return L < a.L;
        }
    };
    multiset<Line> S;
    struct Node{int L,r,mi,mx,sum;}node[N << 2];
    int sz[N],ans = 0,n;
    void Pushup(int idx) {
        node[idx].mx = max(node[idx << 1].mx,node[idx << 1 | 1].mx);
        node[idx].mi = min(node[idx << 1].mi,node[idx << 1 | 1].mi);
        node[idx].sum = node[idx << 1].sum + node[idx << 1 | 1].sum;
    }
    void build(int L,int r,int idx) {
        node[idx].L = L,node[idx].r = r;
        if(L == r) {
            node[idx].mi = node[idx].mx = L;
            node[idx].sum = 1;
            return ;
        }
        int mid = (L + r) >> 1;
        build(L,mid,idx << 1);
        build(mid + 1,r,idx << 1 | 1);
        Pushup(idx);
    }
    void update(int x,int idx,int id) {
        if(node[idx].L == node[idx].r) {
            if(id == 0) node[idx].mx = -INF,node[idx].mi = INF,node[idx].sum = 0;
            else node[idx].mx = node[idx].mi = node[idx].L,node[idx].sum = 1;
            return ;
        }
        int mid = (node[idx].L + node[idx].r) >> 1;
        if(mid >= x) update(x,idx << 1,id);
        else update(x,idx << 1 | 1,id);
        Pushup(idx);
    }
    int query_mi(int L,int r,int idx) {
        if(node[idx].L >= L && node[idx].r <= r) return node[idx].mi;
        int mid = (node[idx].L + node[idx].r) >> 1,mi = INF;
        if(mid >= L) mi = min(mi,query_mi(L,r,idx << 1));
        if(mid < r) mi = min(mi,query_mi(L,r,idx << 1 | 1));
        return mi;
    }
    int query_mx(int L,int r,int idx) {
        if(node[idx].L >= L && node[idx].r <= r) return node[idx].mx;
        int mid = (node[idx].L + node[idx].r) >> 1,mx = -INF;
        if(mid >= L) mx = max(mx,query_mx(L,r,idx << 1));
        if(mid < r) mx = max(mx,query_mx(L,r,idx << 1 | 1));
        return mx;
    }
    int query_sum(int L,int r,int idx) {
        if(node[idx].L >= L && node[idx].r <= r) return node[idx].sum;
        int mid = (node[idx].L + node[idx].r) >> 1,sum = 0;
        if(mid >= L) sum += query_sum(L,r,idx << 1);
        if(mid < r) sum += query_sum(L,r,idx << 1 | 1);
        return sum;
    }
    int cal(int L,int r) {
        int le = 0,ri = 0;
        while(L < 1 || r > n) {}
        int sum = query_sum(L,r,1);
        if(sum <= 1) return 0;
        else {
            le = query_mi(L,r,1);
            ri = query_mx(L,r,1);
            return (ri - le) * 2 + sum;
        }
    }
    void upd_row(int x,int id) {
        if(id == 0) {
            auto L = S.upper_bound(Line{x,x + 1}); --L;
            auto r = S.lower_bound(Line{x,x + 1});
            sz[x]++;
            if(sz[x] == 1) return;
            else {
                if(L->r == x && r->L != x + 1) {
                    ans -= cal(L->L,L->r);
                    ans += cal(L->L,x + 1);
                    S.insert(Line{L->L,x + 1});
                    S.erase(L);
                }
                else if(L->r != x && r->L == x + 1) {
                    ans -= cal(r->L,r->r);
                    ans += cal(x,r->r);
                    S.insert(Line{x,r->r});
                    S.erase(r);
                }
                else if(L->r == x && r->L == x + 1) {
                    ans -= cal(L->L,L->r);
                    ans -= cal(r->L,r->r);
                    ans += cal(L->L,r->r);
                    S.insert(Line{L->L,r->r});
                    S.erase(L);
                    S.erase(r);
                }
                else if(L->r != x && r->L != x + 1){
                    ans += cal(x,x + 1);
                    S.insert(Line{x,x + 1});
                }
            }
        }
        else {
            auto p = S.upper_bound(Line{x, x + 1}); p--;
            sz[x]--;;
            if (sz[x] == 0) return;
            if (p->L == x && p->r == x + 1) {
                ans -= cal(x, x + 1);
                S.erase(p);
            }
            else if (p->L == x && p->r != x + 1)
            {
                ans += cal(x+1,p->r);
                ans -= cal(p->L,p->r);
                S.insert(Line{x+1,p->r});
                S.erase(p);
            }
            else if (p->L != x && p->r == x + 1)
            {
                ans += cal(p->L,x);
                ans -= cal(p->L,p->r);
                S.insert(Line{p->L,x});
                S.erase(p);
            }
            else if (p->L != x && p->r != x + 1)
            {
                ans -= cal(p->L, p->r);
                ans += cal(p->L, x);
                ans += cal(x+1, p->r);
                S.insert(Line{p->L, x});
                S.insert(Line{x+1, p->r});
                S.erase(p);
            }
    
        }
    }
    void upd_line(int x,int id) {
        auto L = S.upper_bound(Line{x,x});L--;
        if(id == 0) {
            if(L->r >= x) {
                ans -= cal(L->L,L->r);
                update(x,1,1);
                ans += cal(L->L,L->r);
            }
            else update(x,1,1);
        }
        else {
            if(L->r >= x) {
                ans -= cal(L->L,L->r);
                update(x,1,0);
                ans += cal(L->L,L->r);
            }
            else update(x,1,0);
        }
    }
    void solve() {
        int m;n = read(),m = read();
        S.clear();
        S.insert(Line{1,n});
        S.insert(Line{-1,-1});
        S.insert(Line{n + 2,n + 2});
        for(int i = 1;i <= n;++i) sz[i] = 2;
        build(1,n,1);
        int allsz = 3 * n - 2;
        ans = 3 * n - 2;
        while(m--) {
            int id,x0,y0,x1,y1;id = read(),x0 = read(),y0 = read(),x1 = read(),y1 = read();
            if(id == 1) {
                allsz++;
                if(x0 == x1) upd_row(min(y0,y1),0);
                else upd_line(min(y0,y1),0);
            }
            else {
                allsz--;
                if(x0 == x1) upd_row(min(y0,y1),1);
                else upd_line(min(y0,y1),1);
            }
            printf("%d
    ",allsz - ans);
        }
    }
    int main() {
        int ca;ca = read();
        while(ca--) {
            solve();
        }
    //    system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    framework7学习笔记
    浮出层的css写法,完美兼容IE6~10
    SpringBoot2.x的c3p0- 0.9.1.2.jar:0.9.1.2]错误
    值溢出
    Jquery+AJAX实现滚动条下拉分页
    springboot+Mybatis多个数据源连接
    mysql批量替换字段中的字符或者字符串
    了解SpringCloud
    SpringBoot2.x访问不了application.properties文件中servlet.context-path上下文路径
    使用mavens创建SpringBoot和Mybatis的web项目
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15351146.html
Copyright © 2011-2022 走看看