CF895C: Square Subsets && 【BZOJ2844】albus就是要第一个出场

这两道题很类似,都是线性基的计数问题,解题的核心思想也一样。

CF895C Square Subsets

题目链接

题意

给定\(n\)个数,求多少种选数方案使得选出来的数乘积为完全平方数。\(n\leq 100000,a_i\leq70\)。

完全平方数的本质就是每个质因子的次数为偶数。

所以我们将每一个数唯一分解,然后记录每个质因子的奇偶状态,就得到了一个个01串。问题就变成了有多少个集合中的数异或为0。

我们建好线性基,设线性基的秩为\(m\),则答案就是\(2^{n-m}-1\)。再判线性基能否组成0,如果能,答案再\(+1\)

因为线性基中的\(m\)个元素是线性无关的,并且可以表达出其他数的所有线性组合,所以其他\(2^{n-m}-1\)(减掉都不选的一种情况)的所有数都能在线性基中找到唯一的一个组合与之异或起来为0。

代码:

#include<bits/stdc++.h>
#define ll long long using namespace std; int n;
ll p[50],cnt;
bool Insert(ll x) {
for(int i=20;i>=0;i--) {
if(!(x>>i)&1) continue ;
if(!p[i]) return p[i]=x,1;
x^=p[i];
}
return 0;
}
ll pri[100];
bool vis[100];
void pre() {
for(int i=2;i<=70;i++) {
if(!vis[i]) pri[++pri[0]]=i;
for(int j=1;j<=pri[0]&&i*pri[j]<=70;j++) {
vis[i*pri[j]]=1;
if(i%pri[j]==0) break;
}
}
}
void break_down(ll v) {
ll x=0;
for(int i=1;i<=pri[0];i++) {
while(v%pri[i]==0) {
x^=1<<i;
v/=pri[i];
}
}
if(!Insert(x)) cnt++;
}
int main() {
pre();
scanf("%d",&n);
ll a;
for(int i=1;i<=n;i++) {
scanf("%lld",&a);
break_down(a);
}
ll t=2,ans=1;
for(;cnt;cnt>>=1,t=t*t%1000000007) {
if(cnt&1)ans=ans*t%1000000007;
}
cout<<(ans-1+1000000007)%1000000007;
return 0;
}

【BZOJ2844】albus就是要第一个出场

题目链接

我们就是要求比\(Q\)小的集合有多少个。

和上一道题一样,我们就是要求比\(Q\)小,且能被线性基表示出来的数有多少个,我们设为\(lower\),则答案为\(lower\cdot 2^{n-m}+1\)。

问题其实就是求\(\leq Q-1\)的的最大的数的\(Rank\)。

我的实现方式不太一样。我们就找\(\leq Q-1\)的数的数量。\(\leq Q-1\)一定是从高到低的前\(i-1\)位相同,第\(i\)位小一些,后面的几位随便。于是我们就考虑\(Q\)的前\(i\)位,我们设为\(Q'\),然后将所有数的前\(i\)位建线性基。问题就变成求有多少种方法能组合出\(Q'\)。

这样做复杂度要比网上的一般写法多一个\(log\),不过个人感觉好理解些。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 100005
#define mod 10086 using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} int n;
int p[35],a[N];
int Q;
bool Insert(int a) {
for(int i=30;i>=0;i--) {
if(a&(1<<i)) {
if(!p[i]) return p[i]=a,1;
else a^=p[i];
}
}
return 0;
}
int cnt;
void build(int k) {
cnt=0;
memset(p,0,sizeof(p));
for(int i=1;i<=n;i++) {
cnt+=Insert(a[i]>>k);
}
}
ll ans;
ll pw[N]; int main() {
n=Get();
pw[0]=1;
for(int i=1;i<=n;i++) pw[i]=(pw[i-1]<<1)%mod;
for(int i=1;i<=n;i++) a[i]=Get();
Q=Get();
for(int i=30;i>=0;i--) {
if(Q&(1<<i)) {
build(i);
if(!Insert((Q>>i)^1)) {
(ans+=pw[n-cnt])%=mod;
}
}
}
cout<<(ans+1)%mod;
return 0;
}

CF895C: Square Subsets && 【BZOJ2844】albus就是要第一个出场的更多相关文章

  1. BZOJ2844: albus就是要第一个出场

    Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2^S定义为S 所有子集构成的集合. 定义映射 f ...

  2. BZOJ2844: albus就是要第一个出场(线性基)

    Time Limit: 6 Sec  Memory Limit: 128 MBSubmit: 2054  Solved: 850[Submit][Status][Discuss] Descriptio ...

  3. bzoj千题计划195:bzoj2844: albus就是要第一个出场

    http://www.lydsy.com/JudgeOnline/problem.php?id=2844 题意:给定 n个数,把它的所有子集(可以为空)的异或值从小到大排序得到序列 B,请问 Q 在  ...

  4. 【贪心】【线性基】bzoj2844 albus就是要第一个出场

    引用题解:http://blog.csdn.net/PoPoQQQ/article/details/39829237 注意评论区. #include<cstdio> using names ...

  5. 【线性基】bzoj2844: albus就是要第一个出场

    线性基求可重rank 题目描述 给定 n 个数 $\{ a_i \}$ ,以及数 $x$. 将 $\{ a_i \}$​ 的所有子集(包括空集)的异或值从小到大排序,得到 $\{ b_i \} $. ...

  6. 【BZOJ2844】albus就是要第一个出场 高斯消元求线性基

    [BZOJ2844]albus就是要第一个出场 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2 ...

  7. BZOJ 2844: albus就是要第一个出场 [高斯消元XOR 线性基]

    2844: albus就是要第一个出场 题意:给定一个n个数的集合S和一个数x,求x在S的$2^n$个子集从小到大的异或和序列中最早出现的位置 一开始看错题了...人家要求的是x第一次出现位置不是第x ...

  8. BZOJ 2844: albus就是要第一个出场

    2844: albus就是要第一个出场 Time Limit: 6 Sec  Memory Limit: 128 MBSubmit: 1134  Solved: 481[Submit][Status] ...

  9. 2844: albus就是要第一个出场

    2844: albus就是要第一个出场 链接 分析: 和HDU3949差不多互逆,这里需要加上相同的数. 结论:所有数任意异或,构成的数出现一样的次数,次数为$2^{n-cnt}$,cnt为线性基的大 ...

随机推荐

  1. 根域名服务器(root DNS Servers)会被DDoS打垮么?

    域名服务作为互联网的基础设施,它的重要性不言而喻.目前全球的十三个根域名服务器和成千上万的授权域名服务器承担着超过万亿次的DNS查询,默默为全世界的网民做域名解析服务. 这样重要的基础设施,必然是全世 ...

  2. Lucene实战之基于StandardAnalyzer读写索引

    前言 使用lucene创建索引时如果指定了解析器,则需要读写都使用这个解析器,目前我发现也就是在处理中文这块比较麻烦,像你在使用solr时如果配置了ik分词,则需要把index清空重新创建才能继续搜索 ...

  3. 深入浅出 JVM GC(4)常用 GC 参数介绍

    # 前言 从前面的3篇文章中,我们分析了5个垃圾收集器,还有一些 GC 的算法,那么,在 GC 调优中,我们肯定会先判断哪里出现的问题,然后再根据出现的问题进行调优,而调优的手段就是 JVM 提供给我 ...

  4. ExtJS4中设置tabpanel的tab高度问题

    最近碰到个问题,在ExtJS中应该如何设置tabpanel的tab的高度?因为默认情况下,tab的高度太矮了,以至于tab的标题底部字都被截掉.设置了个tabpanel.minHeight = ‘50 ...

  5. sort、sorted高级排序-Python3.7 And 算法<七>

    1.sort(*, key=None, reverse=False) sort()接受两个参数,这两个参数只能通过关键字(关键字参数)传递. 参数key:带一个参数的函数(排序时,会依次传入列表的每一 ...

  6. CentOS7 config aliyun yum repository

    https://www.cnblogs.com/lpbottle/p/7875400.html 1. 备份原来的yum源 mv /etc/yum.repos.d/CentOS-Base.repo /e ...

  7. CSS之 :before && :after的用法,伪类和伪元素的区别

    一::before && :after的用法 :before 如同对伪元素的名称一样,:before 是用来给指定的元素的内容前面插入新的内容.举例说明: .before:before ...

  8. 3038 3n+1问题

    3038 3n+1问题  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 白银 Silver 题解       题目描述 Description 3n+1问题是一个简单有趣而又没有 ...

  9. python之线程相关操作

    1.线程: 一个进程可以有多个线程,共享一个进程的资源: 2.进程线程的区别:  进程是资源分配的最小单位,线程是程序执行的最小单位 3.python中线程模块threading, 提供的类: Thr ...

  10. Windows下判断jdk是否安装好以及环境变量是否配置好

    cmd下执行: 1.java 2.javac 3.where java 如果三个都没问题,说明安装成功&环境变量配置成功