• [SHOI2008]堵塞的交通traffic


    这是一道毒瘤题
    只要线段树维护一个矩形的四个点的连通性即可
    合并时请想清楚,要大讨论一番
    询问有可能存在跨区间的联通情况,只要把询问的区间分成[1,l],[l,r],[r,n]再大讨论一番即可
    如果你不想讨论或者讨论出错,你可以使用并查集,每次开并查集更新,这样就不用大讨论一番了,但是会慢,时间几乎是两倍。。。
    像我这种不会讨论的蒟蒻想到了后果断用并查集


    自我感觉代码还是比较短的

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define ZSYbeatME 666
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(4e6 + 10), INF(2e9);
    
    IL ll Read(){
        char c = '%'; ll x = 0, z = 1;
        for(; c > '9' || c < '0'; c = getchar()) if(c == '-') z = -1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
        return x * z;
    }
    
    int n, gg;
    struct Data{
        bool ab, ac, ad, bc, bd, cd;
        IL void Init(){  ab = ac = ad = bc = bd = cd = 0;  }
    } t[_], f[_];
    int fa[4];
    
    IL int Find(RG int x){  return fa[x] == x ? x : fa[x] = Find(fa[x]);  }
    
    IL void Link(RG int x, RG int y){  if(Find(x) != Find(y)) fa[Find(x)] = Find(y);  }
    
    IL bool OK(RG int x, RG int y){  return Find(x) == Find(y);  }
    
    IL void Update(RG Data &A){
        for(RG int i = 0; i < 4; i++) fa[i] = i;
        if(A.ab) Link(0, 1); if(A.ac) Link(0, 2);
        if(A.ad) Link(0, 3); if(A.bc) Link(1, 2);
        if(A.bd) Link(1, 3); if(A.cd) Link(2, 3);
        A.ab = OK(0, 1); A.ac = OK(0, 2);
        A.ad = OK(0, 3); A.bc = OK(1, 2);
        A.bd = OK(1, 3); A.cd = OK(2, 3);
    }
    
    IL Data Merge(RG Data A, RG Data B){
        RG Data C;
        C.ab = A.ab | (A.ad & A.bc & B.ab);
        C.cd = B.cd | (B.ad & B.bc & A.cd);
        C.ac = (A.ac & B.bc) | (A.ad & B.ac);
        C.ad = (A.ad & B.ad) | (A.ac & B.bd);
        C.bc = (A.bc & B.bc) | (A.bd & B.ac);
        C.bd = (A.bd & B.ad) | (A.bc & B.bd);
        Update(C);
        return C;
    }
    
    IL void Modify(RG int x, RG int l, RG int r, RG int id, RG int d, RG bool v){
        if(id < l || id > r) return;
        if(l == r){
            if(d == 0) f[x].ab = v;
            else if(d == 1) f[x].cd = v;
            else if(d == 2) f[x].ad = v;
            else f[x].bc = v;
            t[x] = f[x]; Update(t[x]);
            return;
        }
        RG int mid = (l + r) >> 1;
        if(id <= mid) Modify(x << 1, l, mid, id, d, v);
        else Modify(x << 1 | 1, mid + 1, r, id, d, v);
        t[x] = Merge(t[x << 1], t[x << 1 | 1]);
    }
    
    IL Data Query(RG int x, RG int l, RG int r, RG int L, RG int R){
        RG Data ans; ans.Init();
        if(L > R) return ans;
        if(L <= l && R >= r) return t[x];
        RG int mid = (l + r) >> 1;
        if(R <= mid) return Query(x << 1, l, mid, L, R);
        if(L > mid) return Query(x << 1 | 1, mid + 1, r, L, R);
        ans = Merge(Query(x << 1, l, mid, L, R), Query(x << 1 | 1, mid + 1, r, L, R));
        return ans;
    }
    
    IL bool Calc(RG int a, RG int b, RG int c, RG int d){
        RG Data A = Query(1, 1, n, 1, b - 1), B, C = Query(1, 1, n, d, n);
        if(b == d) return A.cd | C.ab;
        B = Query(1, 1, n, b, d - 1);
        B.ab |= A.cd; B.cd |= C.ab; Update(B);
        if(a == 1 && c == 2) return B.ac;
        if(a == 1 && c == 1) return B.ad;
        if(a == 2 && c == 1) return B.bd;
        if(a == 2 && c == 2) return B.bc;
    }
    
    int main(RG int argc, RG char *argv[]){
        n = Read() - 1; RG char op[10]; RG int a, b, c, d;
        while(ZSYbeatME){
            scanf(" %s", op); if(op[0] == 'E') break;
            a = Read(); b = Read(); c = Read(); d = Read();
            if(b > d) swap(a, c), swap(b, d);
            if(op[0] == 'A') puts(Calc(a, b, c, d) ? "Y" : "N");
            else{
                RG int opt = op[0] == 'O';
                if(b == d) Modify(1, 1, n, b, 0, opt), Modify(1, 1, n, b - 1, 1, opt);
                else Modify(1, 1, n, b, a + 1, opt);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    开博客啦
    C语言 变长参数表的使用方法
    禅道程序员
    【转】函数式编程另类指南
    Servlet中JSP页面跳转的两种方法以及其区别
    《C程序设计语言》(学习笔记)——结构体
    C#保存wps和office表格.数据源为list<T>类型
    中国网建的短信接口实现
    C#保存wps和office表格.数据源为list<T>类型,
    MD5加密
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206335.html
Copyright © 2020-2023  润新知