zoukankan      html  css  js  c++  java
  • 题解 洛谷 P4424 【[HNOI/AHOI2018]寻宝游戏】

    不难发现 (vee 1)(wedge 0) 是会影响到最终结果的,相当于赋值操作,而 (wedge 1)(vee 0) 是无法对结果产生影响的。当某一位最终的结果是 (1) 时,最后一个能产生影响的操作必须是 (vee 1),当最终的结果是 (0) 时,最后一个能产生影响的操作必须是 (wedge 0)

    (n) 个二进制串,对每一位分别来进行考虑,得到 (m) 个长度为 (n) 的二进制串,每一位都对应一个二进制串。把 (veewedge) 的运算序列也看作一个二进制串,(vee) 看作 (0)(wedge) 看作 (1),根据刚才的性质得,若第 (i) 位的最终结果为 (1),则第 (i) 位对应的二进制串要大于运算序列对应的二进制串,若第 (i) 位的最终结果为 (0),则第 (i) 位对应的二进制串要小于等于运算序列对应的二进制串。

    因此先将 (m) 个二进制串排序后,并处理出其对应的权值。对于每个询问串,通过每一位的限制得出运算序列的取值范围,作差即可求解。

    同时还需在边界上加上极大值和极小值,因为两个限制分别是大于和小于等于,所以极大值还需特殊处理,让其权值再加上 (1)

    #include<bits/stdc++.h>
    #define maxn 5010
    #define p 1000000007
    using namespace std;
    typedef long long ll;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,m,q;
    int rnk[maxn];
    ll pw[maxn],val[maxn];
    char str[maxn];
    struct node
    {
        int s[maxn];
        int id;
    }t[maxn];
    bool cmp(const node &a,const node &b)
    {
        for(int i=n;i;--i)
            if(a.s[i]!=b.s[i])
                return a.s[i]<b.s[i];
        return 0;
    }
    int main()
    {
        read(n),read(m),read(q),pw[0]=1;
        for(int i=1;i<=n;++i) pw[i]=pw[i-1]*2%p;
        for(int i=1;i<=n;++i)
        {
            scanf("%s",str+1);
            for(int j=1;j<=m;++j) t[j].s[i]=str[j]-'0';
        }
        for(int i=1;i<=n;++i) t[m+1].s[i]=1;
        for(int i=1;i<=m+1;++i) t[i].id=i;
        sort(t+1,t+m+1,cmp),val[m+1]=1;
        for(int i=1;i<=m+1;++i)
        {
            rnk[t[i].id]=i;
            for(int j=1;j<=n;++j)
                val[i]=(val[i]+pw[j-1]*t[i].s[j])%p;
        }
        while(q--)
        {
            int l=0,r=m+1;
            scanf("%s",str+1);
            for(int i=1;i<=m;++i)
            {
                if(str[i]-'0') r=min(r,rnk[i]);
                else l=max(l,rnk[i]);
            }
            printf("%lld
    ",l>r?0:(val[r]-val[l]+p)%p);
        }
        return 0;
    }
    
  • 相关阅读:
    python——socket,IO多路复用(select),socket server实现多并发
    python——多线程,多进程,协程
    python——装饰器,迭代器,生成器
    time模块,datetime模块
    re模块,paramiko模块
    Freemaker中使用中括号来包含标签
    Freemaker中使用中括号来包含标签
    freemarker Velocity获取request,session
    freemarker Velocity获取request,session
    freemarker Velocity获取request,session
  • 原文地址:https://www.cnblogs.com/lhm-/p/13598831.html
Copyright © 2011-2022 走看看