【推导】【线段树】hdu5929 Basic Data Structure

题意:

维护一个栈,支持以下操作:

从当前栈顶加入一个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;
}
时间: 2024-10-13 21:03:39

【推导】【线段树】hdu5929 Basic Data Structure的相关文章

hdu-5929 Basic Data Structure(双端队列+模拟)

题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 207    Accepted Submission(s): 41 Problem Description Mr. Frog learned a basic data structure recently, which is called

HDU 5929 Basic Data Structure 模拟

Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description Mr. Frog learned a basic data structure recently, which is called stack.There are some basic operations of stack: ? PUSH x: p

HDU 5929 Basic Data Structure

题目:Basic Data Structure 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5929 题意:t个测试数据,每个数据给出一个m表示操作数量,操作分为4种:PUSH x(x:0或1),POP,REVERSE(翻转栈里面的数),QUERY(假使栈内的数一个个出栈,并按出栈顺序将他们与非起来,问最终结果(注意,并不是真的出栈)) 思路: 做题的时候忘记了与非是按出栈顺序来的,一直按栈底到栈顶的顺序来,WA到死... 根据与非的性质,1.0与非

[HDOJ5929]Basic Data Structure(双向队列,规律)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5929 题意:维护一个栈,支持往栈里塞 0/1 ,弹栈顶,翻转栈,询问从栈底到栈顶按顺序 NAND 的值. 题解:只要知道最后的 00 后面 11 的个数的奇偶性就行.可以用链表把所有 00 的位置存下来. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int maxn =

HDU 4217 Data Structure?(线段树 or 树状数组啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4217 Problem Description Data structure is one of the basic skills for Computer Science students, which is a particular way of storing and organizing data in a computer so that it can be used efficiently

OpenJudge cdqz/Data Structure Challenge 2 (Problem 5822) - 可持久化线段树

描述 给一个空数列,有M次操作,每次操作是以下三种之一: (1)在数列后加一个数 (2)求数列中某位置的值 (3)撤销掉最后进行的若干次操作(1和3) 输入 第一行一个正整数M. 接下来M行,每行开头是一个字符,若该字符为'A',则表示一个加数操作,接下来一个整数x,表示在数列后加一个整数x:若该字符为'Q',则表示一个询问操作,接下来一个整数x,表示求x位置的值:若该字符为'U',则表示一个撤销操作,接下来一个整数x,表示撤销掉最后进行的若干次操作. 输出 对每一个询问操作单独输出一行,表示答

ZOJ 4009 And Another Data Structure Problem(ZOJ Monthly, March 2018 Problem F,发现循环节 + 线段树)

题目链接  ZOJ Monthly, March 2018 Problem F 题意很明确 这个模数很奇妙,在$[0, mod)$的所有数满足任意一个数立方$48$次对$mod$取模之后会回到本身. 所以开$48$棵线段树,和一个永久标记.当对某个区间操作时对这个区间加一层永久标记. 即当前我要查找的第$x$层,实际找的是第$up[i] + x$层. 时间复杂度$O(48nlogn)$ #include <bits/stdc++.h> using namespace std; #define

ACM: Copying Data 线段树-成段更新-解题报告

Copying Data Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description We often have to copy large volumes of information. Such operation can take up many computer resources. Therefore, in this problem you are advised to come

LeetCode 211. Add and Search Word - Data structure design(字典树)

题目 字典树. class WordDictionary { public: int map[100005][26]; int tag[100005]; int num; /** Initialize your data structure here. */ WordDictionary() { memset(map,0,sizeof(map)); memset(tag,0,sizeof(tag)); num=0; } /** Adds a word into the data structur