1. 程式人生 > >【推導】【線段樹】hdu5929 Basic Data Structure

【推導】【線段樹】hdu5929 Basic Data Structure

mat string 發現 span print 定義 %d ram 個數

題意:

維護一個棧,支持以下操作:

從當前棧頂加入一個0或者1;

從當前棧頂彈掉一個數;

將棧頂指針和棧底指針交換;

詢問a[top] nand a[top-1] nand ... nand a[bottom]的值。

nand是這樣定義的:

?? 0 nand 0 = 1
?? 0 nand 1 = 1
?? 1 nand 0 = 1
?? 1 nand 1 = 0

關鍵是要發現性質,任何數nand 0,都會變成1。反復nand上1的話,則值會交替變化。

所以假設當前棧頂在左側,只需要找到最右側的0的位置,然後按照其右側1的數量的奇偶性輸出零或者一即可(如果最右側的0在最左端,則其右側有奇數個1就輸出1,否則輸出零。如果最右側的零不在最左端,則其右側有奇數個1就輸出零,否則輸出1)。

棧頂在右側的情況同理。

用線段樹維護。

#include<cstdio>
#include<cstring>
using namespace std;
bool hav[400005<<2];
int a[400005];
int T,m,n,e[2];
void update(int p,int v,int rt,int l,int r){
    if(l==r){
        if(v==0){
            hav[rt]=1;
        }
        else{
            hav[rt]=0;
        }
        return;
    }
    int m=(l+r>>1);
    if(p<=m){
        update(p,v,rt<<1,l,m);
    }
    else{
        update(p,v,rt<<1|1,m+1,r);
    }
    hav[rt]=(hav[rt<<1] || hav[rt<<1|1]);
}
int find1(int rt=1,int l=1,int r=n){
    if(l==r){
        return l;
    }
    int m=(l+r>>1);
    if(hav[rt<<1]){
        return find1(rt<<1,l,m);
    }
    else{
        return find1(rt<<1|1,m+1,r);
    }
}
int find2(int rt=1,int l=1,int r=n){
    if(l==r){
        return l;
    }
    int m=(l+r>>1);
    if(hav[rt<<1|1]){
        return find2(rt<<1|1,m+1,r);
    }
    else{
        return find2(rt<<1,l,m);
    }
}
int main(){
    //freopen("h.in","r",stdin);
    int x;
    bool dir=0;
    char op[10];
    scanf("%d",&T);
    memset(a,-1,sizeof(a));
    for(int zu=1;zu<=T;++zu){
        printf("Case #%d:\n",zu);
        scanf("%d",&m);
        e[0]=m;
        e[1]=m+1;
        n=2*m;
        for(int i=1;i<=m;++i){
            scanf("%s",op);
            if(op[2]==‘S‘){
                scanf("%d",&x);
                if(!dir){
                    a[e[0]]=x;
                    update(e[0],x,1,1,n);
                    --e[0];
                }
                else{
                    a[e[1]]=x;
                    update(e[1],x,1,1,n);
                    ++e[1];
                }
            }
            else if(op[2]==‘P‘){
                if(!dir){
                    ++e[0];
                    a[e[0]]=-1;
                    update(e[0],-1,1,1,n);
                }
                else{
                    --e[1];
                    a[e[1]]=-1;
                    update(e[1],-1,1,1,n);
                }
            }
            else if(op[2]==‘V‘){
                dir^=1;
            }
            else{
                if(e[0]==e[1]-1){
                    puts("Invalid.");
                    continue;
                }
                if(hav[1]){
                    if(!dir){
                        int p=find2();
                        if(p==e[0]+1){
                            puts((e[1]-p-1)%2==1 ? "1" : "0");
                        }
                        else{
                            puts((e[1]-p-1)%2==1 ? "0" : "1");
                        }
                    }
                    else{
                        int p=find1();
                        if(p==e[1]-1){
                            puts((p-e[0]-1)%2==1 ? "1" : "0");
                        }
                        else{
                            puts((p-e[0]-1)%2==1 ? "0" : "1");
                        }
                    }
                }
                else{
                    puts((e[1]-e[0]-1)%2==1 ? "1" : "0");
                }
            }
        }
        memset(a,-1,sizeof(int)*(n+1));
        memset(hav,0,sizeof(bool)*(n*4+1));
    }
    return 0;
}

【推導】【線段樹】hdu5929 Basic Data Structure