【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 clever, and it is very clear that
you will find the solution by considering each one separately. 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 it must put("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://43.154.161.224:23101/article/api/json?id=324723169&siteId=291194637