BZOJ 2844 | HYSBZ - 2844albus就是要第一个出场——线性基

【题目描述】
BZOJ 2844 | HYSBZ - 2844albus
【题目分析】
题目的意思大概是给一个数列,他有2n个子集,每个子集的元素的异或和构成新的一个数列,排序后问数字Q在这个序列里面的下标。
假如题目是求所有元素的异或和构成一个集合就好弄了,我们可以根据求第K大反过来求他在集合里面的下标。

int find_ans(int q){int num=0; int ans=0;vector<int> p;for(int i=0;i<=62;i++){if(b[i]){p.push_back(i);	//如果这个位置有数字,就把这个位置记下来num++;}}for(int i=num-1;i>=0;i--){if(q>>p[i]&1)	//如果这个数字在这一位有数字,那么排名就向前移动1<<i位(在0的基础上){ans+=1<<i;	//这里的i是指这一位前面有多少个高位,也就是说如果这一位是0的数字个数,加上它就是在0的基础上向前移动的排名}}//printf("test: ans=%d num=%d p[0]=%d\n",ans,num,p[0]);return ans+1;//因为前面还有一个0,所以要+1}

可是我们知道这样肯定是求不出答案的,还有好多重复的数字,我们不妨来分析一下这些重复 的数字。对于线性基异或出来的一个数字x,所有和他重复的数字肯定是由那些不包含在线性基里面的数字帮忙异或出来的。
原因是线性基的两个性质:
1.线性基异或出来的数字不相同。
2.线性基无法异或出0。
而这里其他重复的数字相当于线性基的一部分数字异或出 x后再异或一些0(异或0不会改变数值),而通过上面的分析我们知道这些0只能是那些没有进入线性基的数字和一部分进入线性基的 数字异或出来的(当然也可能不包含线性基里面的数字,但肯定不是纯线性基的数字),那么我们能异或出多少个0呢?对于线性基外的每一个数字我们都可以用线性基里面的一部分数字异或出来,所以线性基外的每一个数字配合线性基里的一部分数字都能异或出0,可是不同的0有多少个?我们不妨将线性基外的数字放入一个集合,这个集合的所有子集配合他们相应的能够异或出他们的线性基的数字就能异或出不同的0。而这个子集的个数很好求,2n-num个,n-num为线性基外的数字个数。
所以,我们要做的就是算出q-1前面有多少个数字,然后乘2n-num,再+1就是第一个q的位置。
我们不妨借用上面的程序,上面算出的是在不重复的集合中q的下标,那前面就是(下标-1)*2n-num+1就是答案了。
【AC代码】

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<climits>
#include<cstdlib>
#include<cmath>using namespace std;typedef long long ll;const int MAXN=100005;
const int MOD=10086;
int n,q,tmp;
ll quick_pow(ll a,ll b);	//用快速幂算2^n-num
struct L_B
{ll b[65],p[65];int cnt,flag;L_B(){memset(p,0,sizeof(p));memset(b,0,sizeof(b));cnt=flag=0;}void clear(){memset(p,0,sizeof(p));memset(b,0,sizeof(b));cnt=flag=0;}inline bool insert(ll x){for(int i=62;i>=0;--i)if(x&(1ll<<i)){if(b[i])x^=b[i];else{b[i]=x;return true;}}flag=1;return false;}ll get_max(){ll ret = 0;for(int i=62;i>=0;--i)if((ret^b[i])>ret)ret^=b[i];return ret;}ll get_max(ll initval){ll ret = initval;for(int i=62;i>=0;--i)if((ret^b[i])>ret)ret^=b[i];return ret;}ll get_min(){if(flag)return 0;for(int i=0;i<=62;++i)if(b[i])return b[i];return 0;}inline void rebuild(){for(int i=1;i<=62;++i)if(b[i])for(int j=0;j<i;++j)if(b[i]&(1ll<<j))b[i]^=b[j];for(int i=0;i<=62;++i)if(b[i])p[cnt++]=b[i];}ll kth(ll k){if(flag)--k;if(k==0)return 0;ll ret = 0;if(k>=(1ll<<cnt))return -1;for(int i=0;i<=cnt-1;++i)if(k&(1ll<<i))ret^=p[i];return ret;}int find_ans(int q){int num=0; int ans=0;vector<int> p;for(int i=0;i<=62;i++){if(b[i]){p.push_back(i);num++;}}for(int i=num-1;i>=0;i--){if(q>>p[i]&1){ans+=1<<i;}}//printf("test: ans=%d num=%d p[0]=%d\n",ans,num,p[0]);return (ans*quick_pow(2,n-num))%MOD+1;//ans本来是要+1再-1的,这里就省略了(我之前看其他博客他们好像都没有讲这个然后我就好久都不能理解,emmm,还是太菜了)}
};ll quick_pow(ll a,ll b)
{ll ret=1;while(b){if(b%2) ret=(ret*a)%MOD;a=a*a%MOD;b>>=1;}return ret;
}int main()
{L_B lis;int ans=0;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&tmp);lis.insert(tmp);}scanf("%d",&q);printf("%d",lis.find_ans(q)%MOD);//printf("%lld",quick_pow(2,5));return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CodeForces - 641ELittle Artem and Time Machine——map+树状数组

【题目描述】 CodeForces - 641ELittle Artem and Time Machine 【题目分析】 题目的意思大概是有三种操作 1.在时间t加入一个数字x 2.在时间t删除一个数字x 3.询问在时间t集合里面x的个数 虽然题目描述很简单&#xff0c;但是t和x的范围都是109&#xff0c;我一开始想到的是主…

I/O多路转接之poll 函数

http://blog.csdn.net/li_ning_/article/details/52167224 poll 一、poll()函数&#xff1a; 这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数&#xff0c;自认为poll和select大同小异&#xff0c;下面是这个函数的声明&#xff1a; [cpp] view plaincopy …

链表相关笔试面试题

1.判断两个链表是否相交 两个链表是否相交可分为以下几种情况     &#xff08;1&#xff09;两个链表都不带环&#xff0c;此时两个链表所对应的最后一个节点是相等的     &#xff08;2&#xff09;两个链表一个带环&#xff0c;一个不带环&#xff0c;两个链表一定…

Linux经典问题—五哲学家就餐问题

http://m.blog.csdn.net/aspenstars/article/details/70149038 一、问题介绍 由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。该问题是描述有五个哲学家共用一张圆桌&#xff0c;分别坐在周围的五张椅子上&#xff0c;在圆桌上有五…

修改之前的myshell使之支持输入输出重定向

1.open函数     这个函数是打开一个文件&#xff08;文件名叫pathname),以 flag 权限打开&#xff0c;flag 包括了以下几种 O_RDONLY&#xff08;只读&#xff09;, O_WRONLY&#xff08;只写&#xff09;, O_RDWR&#xff08;读写&#xff09;&#xff0c;当文件打开成…

HDU - 6621 K-th Closest Distance——主席树+二分

【题目描述】 HDU - 6621 K-th Closest Distance 【题目分析】 因为看到第kkk大的要求&#xff0c;刚开始的时候一直都在想怎么运用第kkk大来解决问题&#xff0c;但是后来看其他人的博客才发现并不需要用第k大&#xff0c;但是主席树维护权值线段树还是需要的&#xff0c;这…

链表相关的算法题大汇总 — 数据结构之链表奇思妙想

http://blog.csdn.net/lanxuezaipiao/article/details/22100021基本函数&#xff08;具体代码实现见后面&#xff09; 1&#xff0c;构造节点 //定义节点类型 struct Node { int value; Node*next; }; 2&#xff0c;分配节点 //之所以要分配节点原因是需要在分配函数中…

CodeForces - 372CWatching Fireworks is Fun+DP+单调队列优化

【题目描述】 CodeForces - 372CWatching Fireworks is Fun 题目的大概意思就是在一个编号为1…n的街道上现在按照时间顺序放烟花&#xff0c;每个烟花获得的幸福感为b−abs(a−x)b-abs(a-x)b−abs(a−x)&#xff0c;x为观看烟花的位置&#xff0c;为了提升我们的幸福感&#x…

双向链表的基本操作

1.双向链表的数据结构 typedef char DLinkType;typedef struct DLinkNode { DLinkType data; struct DLinkNode* next; struct DLinkNode* prev; }DLinkNode; 双向带头结点的链表有三个成员&#xff0c; 一个是数据&#xff0c; 一个是指针 next 指向当前结点的下一个结点&…

匿名管道

1.进程通信的目的 (1) 数据传输: 一个进程需要将它的数据传输给另一个进程     (2) 资源共享: 多个进程之间共享同样的资源     (3) 通知事件: 一个进程需要向另一个或一组进程发送消息, 通知它们发生了什么事情 2.管道 管道是一种进程之间通信的一种方式, 我们把从…

Currency Exchange——最短路Bellman-Ford算法

【题目描述】 Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the sam…

C++实现String类

http://blog.csdn.net/randyjiawenjie/article/details/6709539 C实现String类&#xff0c;还没有完成&#xff0c;待继续。 有以下注意的点&#xff1a; &#xff08;1&#xff09;赋值操作符返回的是一个MyString&&#xff0c;而重载的返回的是一个MyString。其中的原因…

POJ 3370 Halloween treats——鸽巢原理+思维

【题目描述】 POJ 3370 Halloween treats Description Every year there is the same problem at Halloween: Each neighbour is only willing to give a certain total number of sweets on that day, no matter how many children call on him, so it may happen that a chi…

将信号量代码生成静态库以及动态库

1.信号量相关代码生成静态库 2.信号量相关代码生成动态库

Wormholes——Bellman-Ford判断负环

【题目描述】 While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of…

C++11 标准新特性:Defaulted 和 Deleted 函数

https://www.ibm.com/developerworks/cn/aix/library/1212_lufang_c11new/index.html Defaulted 函数 背景问题 C 的类有四类特殊成员函数&#xff0c;它们分别是&#xff1a;默认构造函数、析构函数、拷贝构造函数以及拷贝赋值运算符。这些类的特殊成员函数负责创建、初始化、…

顺序表实现栈相关操作

1.栈的相关概念 栈是一种特殊的线性表, 其中只允许在固定的一端进行插入和删除元素.进行数据插入和删除的一端叫做栈顶, 另一端成为栈底. 不含任何元素的栈称为空栈, 栈又称为先进先出的线性表. 2. 顺序栈的结构 3. 顺序栈的具体操作 (1). 数据结构 typedef char SeqStackTyp…

MPI Maelstrom——Dijkstra

【题目描述】 BIT has recently taken delivery of their new supercomputer, a 32 processor Apollo Odyssey distributed shared memory machine with a hierarchical communication subsystem. Valentine McKee’s research advisor, Jack Swigert, has asked her to bench…

双向带环带头结点的链表实现栈

1. 数据结构 利用带头结点带环的结点实现栈的相关操作.因此, 每一个结点包括了一个前驱, 一个后继, 还有一个数据成员 typedef char DLinkStackType;typedef struct DLinkStack {DLinkStackType data;struct DLinkStack* next;struct DLinkStack* prev; }DLinkStack;2. 初始化…

Cow Contest——Floyed+连通性判断

【题目描述】 N (1 ≤ N ≤ 100) cows, conveniently numbered 1…N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors. The contest …