zoukankan      html  css  js  c++  java
  • [十二省联考2019]异或粽子

    前言

    去年打酱油的时候,我还不会字典树= =

    貌似我( equire{enclose}enclose{horizontalstrike}{O(n^2logn)})的分都没拿满?

    题目

    洛谷

    讲解

    异或?l~r的连续区间?

    明显可以前缀和优化

    接下来就变成了求前(k)大的点对异或值了

    看题解得知,这种类型的问题可以这么解决:

    先把所有的前缀和插入进一棵字典树中,注意要插入0

    此字典树需要记录的信息有:

    1.两个儿子(常规操作)

    2.子树大小(记录这条路走下去可以最多选出多少个数)

    然后我们可以将每一个前缀和的查询的最大值插进优先队列

    每次取出最大的一个,累加答案,然后求出次大的值,放回优先队列...

    循环做(k)次,就完事了

    吗?

    NO!由于(s_i oplus s_j=s_j oplus s_i),所以每个较大值会出现两次,我们要将(2k)个较大数累加起来,最后将答案除以二即可

    时间复杂度为(O(nlog_2n))

    注意开(long long)

    代码

    //12252024832524
    #include <queue>
    #include <cstdio>
    #include <algorithm>
    using namespace std; 
    
    typedef long long LL;
    const int MAXN = 500005;
    const int MAXLOG = 32;
    int n,k;
    LL s[MAXN],ans;
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    void Put1(LL x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    void Put(LL x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x);
    	if(c >= 0) putchar(c);
    }
    template <typename T>T Max(T x,T y){return x > y ? x : y;}
    template <typename T>T Min(T x,T y){return x < y ? x : y;}
    template <typename T>T Abs(T x){return x < 0 ? -x : x;}
    
    struct Node
    {
    	int ID,rk;
    	LL val;
    	Node(){}
    	Node(int ID1,int rk1,LL val1){
    		ID = ID1;
    		rk = rk1;
    		val = val1;
    	}
    	bool operator < (const Node &px) const{
    		return val < px.val;
    	}
    };
    priority_queue<Node> q;
    
    int tot;
    struct node
    {
    	int ch[2],siz;
    }t[MAXN * MAXLOG];
    void ins(LL x)
    {
    	int now = 0;
    	for(int i = MAXLOG - 1;i >= 0;-- i)
    	{
    		bool ID = x >> i & 1;
    		if(!t[now].ch[ID]) t[now].ch[ID] = ++tot;
    		now = t[now].ch[ID];
    		t[now].siz++;
    	}
    }
    LL query(int rk,LL w)
    {
    	int now = 0;
    	LL ret = 0;
    	for(int i = MAXLOG - 1;i >= 0;-- i)
    	{
    		bool ID = w >> i & 1,to = ID ^ 1;
    		if(t[now].ch[to]) 
    		{
    			if(t[t[now].ch[to]].siz >= rk) now = t[now].ch[to],ret += 1ll << i;
    			else rk -= t[t[now].ch[to]].siz,now = t[now].ch[ID];
    		}
    		else now = t[now].ch[ID];
    	}
    	return ret;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read(); k = Read() << 1;
    	for(int i = 1;i <= n;++ i) s[i] = Read() ^ s[i-1];
    	for(int i = 0;i <= n;++ i) ins(s[i]);
    	for(int i = 0;i <= n;++ i) q.push(Node(i,1,query(1,s[i])));
    	while(k--)
    	{
    		Node g = q.top(); q.pop(); ans += g.val;
    		if(g.rk < n) q.push(Node(g.ID,g.rk+1,query(g.rk+1,s[g.ID])));
    	}
    	Put(ans >> 1);
    	return 0;
    }
    
  • 相关阅读:
    BZOJ 1191 HNOI2006 超级英雄hero
    BZOJ 2442 Usaco2011 Open 修建草坪
    BZOJ 1812 IOI 2005 riv
    OJ 1159 holiday
    BZOJ 1491 NOI 2007 社交网络
    NOIP2014 D1 T3
    BZOJ 2423 HAOI 2010 最长公共子序列
    LCA模板
    NOIP 2015 D1T2信息传递
    数据结构
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/13392000.html
Copyright © 2011-2022 走看看