Formurosa(CF-217C)

Problem Description

The Bytelandian Institute for Biological Research (BIBR) is investigating the properties of two species of bacteria, named simply 0 and 1. Even under a microscope, bacteria of those two species are very difficult to distinguish. In fact, the only thing the scientists possess that is able to differentiate between them is a plant called Formurosa.

If the scientists place a sample of colonies of bacteria on each on Formurosa's leaves, it will activate a complicated nutrition process. During that process color of Formurosa changes to reflect the result of a — possibly very complicated — logical formula on the species of bacteria, involving constants and the operators | (OR), & (AND) and ^ (XOR). If it is 0, the plant will turn red, otherwise — it will turn blue.

For example, if the nutrition process of Formurosa is described by the formula: (((?^?)|?)&(1^?)); then Formurosa has four leaves (the "?" signs denote the leaves). If we place 0, 1, 0, 0 on the respective leaves, the result of the nutrition process will be (((0^1)|0)&(1^0)) = 1, therefore the plant will turn blue.

The scientists have n colonies of bacteria. They do not know their types; the only thing they know for sure is that not all colonies are of the same type. They want to attempt to determine the bacteria's species by repeated evaluations with Formurosa. During each evaluation they must place exactly one sample on every leaf of the plant. However, they may use multiple samples of one colony during a single evaluation; they can even cover the whole plant with bacteria from one colony!

Is it possible for them to always determine the species of each colony, no matter what they are (assuming they are not all the same)?

Input

The first line of input contains a single integer n (2 ≤ n ≤ 106) — the number of colonies of bacteria.

The second line contains the formula describing the nutrition process of Formurosa. This line contains only characters «0», «1», «?», «|», «&», «^», «(», «)» and complies with the following grammar:

s → 0|1|?|(s|s)|(s&s)|(s^s)
The formula consists of no more than 106 characters.

Output

If it is always possible to determine the species of each colony, output "YES" (without quotes). Otherwise, output "NO" (without quotes).

Examples

Input

2
(?^?)

Output

NO

Input

10
?

Output

YES

题意:有 n 个细菌,分为两类 0、1,需要进行种类区分,现在有一种叶子经过一系列变换后可以区分细菌的种类,给出一串由 ?、^、&、|、() 组成的字符串,其中 ? 代表一片叶子,需要在上面放一个细菌,即可以放 0 也可以放 1,如果按照给定的字符串进行位运算后,得出的结果是唯一确定的,则输出 YES,反之,输出 NO

思路:

问题本质是在给出的序列中,将 ?任意填为 1、0,如果最后的结果总是一样,则认为是同一类

假设给出序列的过程是一个函数 F(s),其将长度为 m 的二进制序列映射到 {0,1} 

因此,问题可以描述为:当且仅当存在长度为 m 的序列 s 时,可以区分所有的细菌,即有 F(s)≠F(-s),其中,s 是 -s 的否定

 如果不存在这样的序列,那么就无法区分 0、1,反之,如果存在这样的序列,可以挑选任意两种细菌 a、b,并尝试两种方法将他们替换进表达式,如果两个表达式的值不同,则可以确定两种细菌的类型,反之,将确定细菌属于同一类

为了确定这样的序列是否存在,可以通过递归来解决:

  • 序列 s 使得 G(s)=G(-s)=0
  • 序列 s 使得 G(s)=G(-s)=1
  • 序列 s 使得 G(s)≠G(-s)

Source Program

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 5000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;

char get(char x,char y,char ch) {
    if(ch=='&')
        return x&y;
    else if(ch=='|')
        return x|y;
    else if(ch=='^')
        return x^y;
}
char work() {
    char ch=getchar();
    char res=0;
    if(ch=='(') {
        char L=work();//左端表达式
        char opr=getchar();//运算符
        char R=work();//右端表达式
        getchar();

        for(char i=0; i<4; i++)
            if(L&1<<i)
                for(char j=0; j<4; j++)
                    if(R&1<<j)
                        res|=1<<get(i,j,opr);
        return res;
    }
    else{
        if(ch=='0')
            return 1;//0001
        else if(ch=='1')
            return 8;//1000
        else
            return 6;//0110
    }
}
int main() {
    int n;
    scanf("%d ",&n);
    if(work()&6)
        printf("YES\n");
    else
        printf("NO\n");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值