zoukankan      html  css  js  c++  java
  • 【NOIP2014模拟11.1B组】吴传之火烧连营

    trie,动态开点。
    我们可以将输入的a[],b[]全部看成二进制数。
    然后按照二进制中的位置从大到小开始建trie。
    如果trie不会的可以自己手动普及一下。
    建好a[]的trie后,我们可以对于每个b[i]开始求答案。
    答案可以说是贪心来求的。正确性可以保证。
    如果对于当前结点:
    1:只有一个儿子,那就走那一个儿子。
    2:否则的话就按照与b[i]的这一位置上的0/1取反,并走那一个儿子。
    这样子我们可以保证答案的最优性了。
    上标:

    #include<cstdio>
    using namespace std;
    int n,m,x,f[2000010][3],tot=1;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    void insert(int id,int x)
    {
    	int now=1;
    	for (int i=30,j;i>=0;i--)
    	{
    		j=(x & (1<<i)) ? 1:0;
    		if (!f[now][j]) f[now][j]=++tot;
    		now=f[now][j];
    	}
    	f[now][2]=id;
    }
    
    int find(int x)
    {
    	int now=1;
    	for (int i=30;i>=0;i--)
    	{
    		if (!f[now][0]) now=f[now][1];
    		else if (!f[now][1]) now=f[now][0];
    		else now=f[now][!(x & (1<<i))];
    	}
    	return f[now][2];
    }
    
    int main()
    {
    	freopen("wu.in","r",stdin);
    	freopen("wu.out","w",stdout);
    	n=read(),m=read();
    	for (int i=1;i<=n;i++)
    		x=read(),insert(i,x);
    	for (int j=1;j<=m;j++)
    		x=read(),printf("%d
    ",find(x));
    	return 0;
    }
    
    
    转载需注明出处。
  • 相关阅读:
    剖析C语言中a=a+++++a的无聊问题
    [转]精确到1%秒的单片机计时器汇编程序
    [转]学DSP、FPGA、ARM,哪个更有前途?
    【Java】Eclipse导出JAR包
    二维码生成器(支持历史记录点击和清空)
    移动端开发注意之一二
    localStorage实现按钮点击禁用
    JavaScript之查找元素
    扒拉扒拉table
    解惑之JavaScript
  • 原文地址:https://www.cnblogs.com/jz929/p/11817583.html
Copyright © 2011-2022 走看看