求助,为什么这个思路不对
查看原帖
求助,为什么这个思路不对
922019
xiaoniu142857楼主2024/12/25 09:37

将所有 aia_i 插入到 01Trie 中,统计每一个子树下串的总数。从高到低枚举 kk 和所有 aia_i 的每一位。

kk 这一位为1,且所有 aia_i 这一位为1的多,则 xx 这一位设置为1,ans 加入 aia_i 这一位为1的数量,否则设为0,ans 加入 aia_i 这一位为0的数量。

kk 这一位为0,且所有 aia_i 这一位为1的多,则 xx 这一位设置为1,舍弃 aia_i 这一位为0的,否则设为0,舍弃 aia_i 这一位为1的。

为什么这个做法只能通过样例和 #8#9 两个点?求 Hack 和正解。

#include <cstdio>
using namespace std;
const int N=10485760;
const int L=19;
struct Node
{
    int ch[2],cnt;
}t[N];
char buf[1<<20],*p1,*p2;
int len=1,ans=0,n,k;
inline char gc()
{
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==buf?EOF:*p1++;
}
inline void read(int &x)
{
    char c;
    while((c=gc())<'0'||c>'9');
    for(x=c^48;(c=gc())>='0'&&c<='9';x=(x<<3)+(x<<1)+(c^48));
}
inline void insert(int x)
{
    int cur=1,bit;
    for(int i=L;i>=0;--i)
    {
        ++t[cur].cnt;
        bit=x>>i&1;
        if(!t[cur].ch[bit]) t[cur].ch[bit]=++len;
        cur=t[cur].ch[bit];
    }
    ++t[cur].cnt;
}
inline void getans()
{
    int cur=1,bit,l,r;
    for(int i=L;i>=0;--i)
    {
        bit=k>>i&1;
        l=t[cur].ch[0];
        r=t[cur].ch[1];
        if(bit)
        {
            if(t[l].cnt>t[r].cnt)
            {
                ans+=t[l].cnt;
                cur=r;
            }
            else
            {
                ans+=t[r].cnt;
                cur=l;
            }
        }
        else
        {
            if(t[l].cnt>t[r].cnt) cur=l;
            else cur=r;
        }
    }
}
int main()
{
    int x;
    read(n),read(k);
    while(n--)
    {
        read(x);
        insert(x);
    }
    getans();
    printf("%d",ans);
    return 0;
}
2024/12/25 09:37
加载中...