zoukankan      html  css  js  c++  java
  • 【6.28校内test】T3 【音乐会】道路千万条

    【音乐会】道路千万条【题目链接】

    首先,你可以忽略上面的一大坨题面,只需要看说明的那一小部分就好啦。

    然后理解题意:

    就是说我们要给这n-1个运算符指定一个顺序,统计所有值为true的方案数pt,统计所有值为false的方案数pf,然后算pt/(pt+pf) mod 998244353

    然后water_lift就想到了表达式的值【题解】,考虑最后算哪个运算符,一共有n-1种选择。

    然后三种情况:

    1.最后计算的运算符是‘&’。

    那么使表达式为true的方案数就是运算符左边为true的方案数*运算符右边为true的方案数(乘法原理)。

    使表达式为false的方案数是左边为true*右边为false+左边false*右边true+左边false*右边false。

    2.最后计算的运算符是‘|’。

    那么使表达式为true的方案数为:左边true*右边false+左边false*右边true+左边true*右边true;

    使表达式为false的方案数为:左边false*右边false;

    3.最后计算的运算符是'^'。

    那么使表达式为true的方案数为:左边false*右边true+左边true*右边false;

    使表达式为false的方案数为:左边false*右边false+左边true*右边true;

    所以定义两个数组,t[l][r]表示区间[l,r]为true的方案数,f[l][r]表示区间[l,r]为false的方案数。

    那么最终答案就是t[1][n]/(t[1][n]+f[1][n])mod 998244353;

    然后显然是可以搜索的,但是我写锅了(并且我不想看

    因此我们还是看DP的解法吧;

    就是类比表达式的值,然后求就好辣;(主要是不知道该写啥qwq)

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int read(){
        int ans=0;
        char last=' ',ch=getchar();
        while(ch>'9'||ch<'0') last=ch,ch=getchar();
        while(ch<='9'&&ch>='0') ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); 
        if(last=='-') ans=-ans;
        return ans;
    }
    
    inline char gc(){
        char c;
        do{
            c=getchar();
        }while(c==' '||c=='
    '||c=='
    '||c==''||c=='	');
        return c;
    }
    
    int n;
    char s[501],ops[501];
    long long t[501][501],f[501][501];
    const int mod=998244353;
    pair<long long,long long>extgcd(long long a,long long b){
        if(b==0){
            return make_pair<long long ,long long>(1,0);
        }
        pair<long long,long long>rtn=extgcd(b,a%b);
        rtn.first^=rtn.second^=rtn.first^=rtn.second;//交换两个变量 
        rtn.second-=a/b*rtn.first;
        return rtn;
    }
    
    int main(){
        n=read();
        for(int i=1;i<=n-1;i++){
            s[i]=gc();
            ops[i]=gc();
        }
        s[n]=gc();
        for(int i=1;i<=n;i++){
            if(s[i]=='t')
              t[i][i]=1,f[i][i]=0;
            else 
              t[i][i]=0,f[i][i]=1;
        }
        for(int len=2;len<=n;len++){
            for(int i=1;i+len-1<=n;i++){
                int j=i+len-1;
                for(int k=i;k<j;k++){
                    if(ops[k]=='&'){
                    t[i][j]=(t[i][j]+(t[i][k]*t[k+1][j])%mod)%mod;
                    f[i][j]=(f[i][j]+(t[i][k]*f[k+1][j])%mod+(f[i][k]*t[k+1][j])%mod+(f[i][k]*f[k+1][j])%mod)%mod; 
                    }
                    if(ops[k]=='|'){
                        f[i][j]=(f[i][j]+(f[i][k]*f[k+1][j])%mod)%mod;
                        t[i][j]=(t[i][j]+(t[i][k]*f[k+1][j])%mod+(f[i][k]*t[k+1][j])%mod+(t[i][k]*t[k+1][j])%mod)%mod;
                    }
                    if(ops[k]=='^'){
                        t[i][j]=(t[i][j]+(t[i][k]*f[k+1][j])%mod+(f[i][k]*t[k+1][j])%mod)%mod;
                        f[i][j]=(f[i][j]+(f[i][k]*f[k+1][j])%mod+(t[i][k]*t[k+1][j])%mod)%mod;
                    }
                }
            }
        }
        cout<<(t[1][n]*((extgcd(t[1][n] +f[1][n]%mod,mod).first%mod+mod)%mod))%mod<<endl;
        return 0;
    }

    end-

  • 相关阅读:
    Linux 常用命令
    Oracle DG 三种模式(转)
    S5PV2210
    Timer wheel etc.
    SCM etc.
    负载均衡 IO etc.
    Remoting,OData Snippet Compiler等
    displaytag 动态列实现
    <display:column>属性解释
    <display:table>属性解释
  • 原文地址:https://www.cnblogs.com/zhuier-xquan/p/11103652.html
Copyright © 2011-2022 走看看