• 第k大异或值


    这道题与2018年十二省联考中的异或粽子很相像,可以算作一个简易版;

    因为这不需要可持久化;

    也就是说求任意两个数异或起来的第k大值;

    trie

    trie

    kk使mid

    midk01

    O(nlog^2n)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=50005,maxm=200005,M=15;
    typedef long long LL;
    int n,a[maxn],l,r,mid;
    LL m,ans,sum[maxm],t;
    char c;
    int read()
    {
    	for (c=getchar();c<'0' || c>'9';c=getchar());
    	int x=c-48;
    	for (c=getchar();c>='0' && c<='9';c=getchar()) x=x*10+c-48;
    	return x;
    }
    void insert(int x,int num,int w)
    {
    	sum[x]++;
    	if (w<0) return;
    	if ((num&(1<<w))==0) insert(x<<1,num,w-1);else insert(x<<1|1,num,w-1);
    }
    int query(int x,int num,int w,int now)
    {
    	if (w<0) return sum[x];
    	int t=((num&(1<<w))>0);
    	if ((now&(1<<w))==0) return query(x<<1|t,num,w-1,now)+sum[x<<1|(t^1)];
    	return query(x<<1|(t^1),num,w-1,now);
    }
    bool check(int x)
    {
    	if (!x) return 1;
    	ans=0;
    	for (int i=0;i<n;i++) ans+=query(1,a[i],M,x);
    	if (ans>=m) return 1;
    	return 0;
    }
    int main()
    {
    	scanf("%d%lld",&n,&m);
    	for (int i=0;i<n;i++) insert(1,a[i]=read(),M);
    	for (l=0,r=(1<<(M+1))-1,mid=r>>1;l<r;mid=l+r>>1)
    		if (check(mid)) l=mid+1;else r=mid;
    	if (!check(l)) l--;
    	printf("%d
    ",l);
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    【2018 “百度之星”程序设计大赛
    分班级(经典二分)
    【2018 “百度之星”程序设计大赛
    【zznu-夏季队内积分赛3-J】追忆
    常见网络名词解释
    【zznu-夏季队内积分赛3-G】2333
    【zznu-夏季队内积分赛3-F】学无止境
    【zznu-夏季队内积分赛3-I】逛超市
    html/css/javascript练习代码
    花生壳免费域名80端口无法访问问题处理
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11759597.html
Copyright © 2020-2023  润新知