【Competition】HNOI2018 Treasure Hunt

enter image description here
enter image description here

I took 30 points when I took the test and got rough.
I heard that myy was very helpless about the backward method of this question. The official solution is here.
The correct solution is really ingenious, and it is very clear
that considering each one separately, you will find the solution that property in , and then put the binary numbers of the query according to the sorted position. If there is a 1 behind 0, then definitely puts("0"), otherwise according to that formula, each bit must satisfy that condition , and finally the range continues to shrink, and it becomes the difference between the two numbers

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=1000+10,MAXM=5000+10,Mod=1e9+7;
ll total;
int n,m,q,r[MAXM];
char bin[MAXM];
template<typename T> inline void read(T &x)
{
    T data=0,w=1;
    char ch=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
    if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline ll qexp(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1)res=res*a%Mod;
        a=a*a%Mod;
        b>>=1;
    }
    return res;
}
struct data{
    int b[MAXN],id;
    ll ans;
    data(){ans=-1;}
    inline bool operator < (const data &A) const {
        for(register int i=1;i<=n;++i)
            if(b[i]!=A.b[i])return b[i]>A.b[i];
        return false;
    };
    inline ll value()
    {
        if(~ans)return ans;
        ans=0;
        for(register int i=1;i<=n;++i)(ans+=b[i]*qexp(2,n-i))%=Mod;
        return ans;
    }
};
data infin[MAXM];
int main()
{
    freopen("hunt.in","r",stdin);
    freopen("hunt.out","w",stdout);
    read(n);read(m);read(q);
    for(register int i=1;i<=n;++i)
    {
        scanf("%s",bin+1);
        for(register int j=1;j<=m;++j)infin[j].b[n-i+1]=bin[j]-'0';
    }
    for(register int i=1;i<=m;++i)infin[i].id=i;
    total=qexp(2,n);
    std::sort(infin+1,infin+m+1);
    while(q--)
    {
        scanf("%s",bin+1);
        for(register int i=1;i<=m;++i)r[i]=bin[infin[i].id]-'0';
        int p0=m+1,p1=0;
        for(register int i=m;i>=1;--i)
            if(!r[i])p0=i;
        for(register int i=1;i<=m;++i)
            if(r[i])p1=i;
        if(p0<p1)puts("0");
        else if(p0==1)write((total-infin[1].value()+Mod)%Mod,'\n');
        else if(p0==m+1)write(infin[m].value(),'\n');
        else write((infin[p0-1].value()-infin[p0].value()+Mod)%Mod,'\n');
    }
    return 0;
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326573930&siteId=291194637