zoukankan      html  css  js  c++  java
  • [SDOI2008] 校门外的区间

    U T 即将区间 (T) 范围赋值为 (1)

    I T 即将区间 (U - T) 范围赋值为 (0)

    D T 即将区间 (T) 赋值为 (0)

    C T 由于 (S=T-S=T(U-S)),即将原状态取反后,将 (U-T) 范围赋值为 (0)

    S T 即将区间 (T) 翻转

    至于开闭区间,我们不妨把下标缩放到原来的两倍,然后在输入输出的时候讨论一下即可

    这题的输入真的挺正常(鬼畜)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1000005;
    
    int a[N],tag[N],rev[N],n,m,t1,t2,t3;
    
    void settag(int p) {
        rev[p]=0; tag[p]=1;
    }
    
    void setrev(int p) {
        rev[p]^=1;
    }
    
    void pushdown(int p) {
        if(tag[p]) {
            tag[p*2]=tag[p*2+1]=1;
            rev[p*2]=rev[p*2+1]=0; // Error
            tag[p]=0;
        }
        if(rev[p]) {
            rev[p*2]^=1;
            rev[p*2+1]^=1;
            rev[p]=0;
        }
    }
    
    void modify(int p,int l,int r,int ql,int qr,int ist,int isr) {
        if(ql > qr) return;
        if(l>qr || r<ql) return;
        if(l>=ql && r<=qr) {
            if(ist) settag(p);
            if(isr) setrev(p);
        }
        else {
            pushdown(p);
            modify(p*2,l,(l+r)/2,ql,qr,ist,isr);
            modify(p*2+1,(l+r)/2+1,r,ql,qr,ist,isr);
        }
    }
    
    void traverse(int p,int l,int r) {
        if(l==r) {
            if(tag[p] && !rev[p]) a[l]=1;
            else a[l]=0;
        }
        else {
            pushdown(p);
            traverse(p*2,l,(l+r)/2);
            traverse(p*2+1,(l+r)/2+1,r);
        }
    }
    
    int main() {
        n=65536*2;
        char op,p,q;
        while(~scanf("%c %c%d,%d%c
    ",&op,&p,&t1,&t2,&q)) {
            ++t1, ++t2;
            if(p=='(') t1=t1*2+1;
            else t1=t1*2;
            if(q==')') t2=t2*2-1;
            else t2=t2*2;
            if(t1>t2) continue;
            if(op=='U') modify(1,1,n,t1,t2,1,0);
            if(op=='I') modify(1,1,n,2,t1-1,1,1), modify(1,1,n,t2+1,n,1,1);
            if(op=='D') modify(1,1,n,t1,t2,1,1);
            if(op=='C') modify(1,1,n,2,n,0,1), modify(1,1,n,2,t1-1,1,1), modify(1,1,n,t2+1,n,1,1);
            if(op=='S') modify(1,1,n,t1,t2,0,1);
        }
        traverse(1,1,n);
        int last=0,flag=0;
        for(int i=1;i<=n+1;i++) { // Error n->n+1
            if(last==0 && a[i]==1) last=i;
            if(last && a[i]==0) {
                int l=last, r=i-1;
                flag=1;
                if(l&1) printf("(%d,",l/2-1);
                else printf("[%d,",l/2-1);
                if(r&1) printf("%d) ",(r-1)/2);
                else printf("%d] ",(r-1)/2);
                last=0;
            }
        }
        if(flag==0) cout<<"empty set";
    }
    
  • 相关阅读:
    第二十九课 循环链表的实现
    第二十八课 再论智能指针(下)
    第二十七课 再论智能指针(上)
    第二十六课 典型问题分析(Bugfix)
    普通new和placement new的重载
    leetcode 581. Shortest Unsorted Continuous Subarray
    leetcode 605. Can Place Flowers
    leetcode 219. Contains Duplicate II
    leetcode 283. Move Zeroes
    leetcode 217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/mollnn/p/12289916.html
Copyright © 2011-2022 走看看