2 条题解

  • 0
    @ 2026-5-18 19:09:01

    显然可以直接将 [l,r][l,r] 的一大串直接替换为目标布尔值,再计算结果,判断最后得到的结果是否与期望相同,而不需要去试应该填 true 还是 false

    那么原问题转化为:每次给出 l,r,xl,r,x,将 [l,r][l,r] 替换为 xx 再求值。

    把整个表达式按 or 分隔成若干块,可以 O(n)O(n) 预处理出:

    1. 每一块的值;
    2. 每一个 truefalse 在哪一块;
    3. 每一个 truefalse 所在的块前面 and 起来的值;
    4. 每一个 truefalse 所在的块后面 and 起来的值;
    5. 每一个 truefalse 所在的块前面所有块的值 or 起来的值;
    6. 每一个 truefalse 所在的块后面所有块的值 or 起来的值。

    将上面提到的六个值用六个数组存起来,下面分别把它们命名为 ai,bi,bpi,bsi,api,asia_i,b_i,bp_i,bs_i,ap_i,as_i

    预处理后,对于每个询问,输入完 l,r,xl,r,x,接着就可以这样 O(1)O(1) 计算最后的值:

    1. apl=1ap_l=1,结果为 11
    2. 否则若 asr=1as_r=1,结果为 11
    3. 否则最终结果为“这个块”([bl,br][b_l,b_r] 合并后的一大块)的最终结果。若 bpl=0bp_l=0,结果为 00
    4. bsr=0bs_r=0,结果为 00
    5. 否则最终结果为 xx
    #include<bits/stdc++.h>
    using namespace std;
    const int N=200005;
    string s[N];
    bool f(string s){return s=="true";};
    int a[N],b[N];
    bool bp[N],bs[N],ap[N],as[N],aa[N];
    int c[N];//每一块的第一个位置 
    int cnt=0;
    int n;
    void init(){
    	s[0]="or";
    	for(int i=1;i<=n;i+=2){
    		if(s[i-1]=="or"){
    			//新的一块
    			b[i]=++cnt;
    			c[cnt]=i;
    			bp[i]=1;
    			a[cnt]=f(s[i]);
    			ap[i]=ap[c[b[i]-1]]|a[cnt-1];
    		}else{
    			b[i]=cnt;
    			bp[i]=a[cnt];
    			a[cnt]&=f(s[i]);
    			ap[i]=ap[c[b[i]-1]]|a[cnt-1];
    		}
    	}
    	s[n+1]="or";
    	cnt=0;
    	for(int i=n;i>=1;i-=2){
    		if(s[i+1]=="or"){
    			bs[i]=1;
    			aa[++cnt]=f(s[i]);
    			as[i]=as[c[b[i]+1]]|aa[cnt-1];
    		}else{
    			bs[i]=aa[cnt];
    			aa[cnt]&=f(s[i]);
    			as[i]=as[c[b[i]+1]]|aa[cnt-1];
    		}
    	}
    }
    bool query(int l,int r,string x){
    	if(ap[l])return 1;
    	if(as[r])return 1;
    	if(bp[l]==0)return 0;
    	if(bs[r]==0)return 0;
    	return f(x);
    }
    int main(){
    	ios::sync_with_stdio(0);cin.tie(0);
    	int q;cin>>n>>q;
    	for(int i=1;i<=n;i++){
    		cin>>s[i];
    	}
    	init();
    	for(int i=1;i<=q;i++){
    		int l,r;string x;cin>>l>>r>>x;
    		if(query(l,r,x)==f(x))cout<<"Y";
    		else cout<<"N";
    	} 
    	return 0;
    }
    
    • 0
      @ 2025-10-8 17:14:14
      #include <bits/stdc++.h>
      using namespace std;
      const int INF=1e9;
      int main()
      {
          ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
          int n, q;cin >> n >> q;
          vector<string> s(n+1);
          for(int i=1;i<=n;i++)cin >> s[i];
      
          vector<int> orgroup(n+1);
          int orlen=1;
          for(int i=1;i<=n;i++)
          {
              if(i%2==1)orgroup[i]=orlen;
              else
              {
                  if(s[i]=="or")orlen++;
              }
          }
      
          vector<int> fst_False(orlen+1, INF);
          vector<int> lst_False(orlen+1, -1);
          for(int i=1;i<=n;i+=2)
              if(s[i]=="False")
              {
                  int g=orgroup[i];    lst_False[g]=i;
                  if(fst_False[g]==INF)fst_False[g]=i;
              }
      
          int tot_fst_True=INF, tot_lst_True=-1;
          for(int i=1;i<=orlen;i++)
          {
              if(fst_False[i]==INF)
      • 1

      *【思维细节】布尔语句替换[USACO24OPEN] Logical Moos B

      信息

      ID
      7633
      时间
      2000ms
      内存
      256MiB
      难度
      7
      标签
      递交数
      42
      已通过
      9
      上传者