51nod 1407 与与与与

2023-12-07 03:58
文章标签 51nod 1407

本文主要是介绍51nod 1407 与与与与,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1407 与与与与
题目来源: CodeForces
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 320 难度:7级算法题
有n个整数,问从他们中取出若干个数字相与之后结果是0的有多少组。
答案比较大,输出对于 1,000,000,007 (1e9+7)取模后的结果。
Input
第一行输入一个整数n。(1<=n<=1,000,000).
第二行有n个整数a[0],a[1],a[2],...a[n-1],以空格分开.(0<=a[i]<=1,000,000)
Output
对于每一组数据,输出一个整数。
Input示例
3
2 3 3
4
0 1 2 3
Output示例
0

10

题解:对于我这中蒟蒻来说就是神题,看了一天才真正看明白。对于几个数&等于0,有非常多种情况而且状态不好表示,所以就用总的组合方案数(2^n-1)减去相&!=0的方案数即合法方案数。对于几个数&!=0,那么转化成二进制数来看,也就是说n个数最大能合成2^20-1,2^20约等于1000000。那么就枚举0到2^20-1的所有数,其中必定包含所有的ai和所有ai组合合成的数。对于每一个ai,如果aj&ai!=0,那么ai和aj在二进制状态下一定有一位同时为一,那么需要找出ai的所有位中为1的位,在其他a中那些为也为1的和ai组合一定为1,设f【i】表示和i这个数相&任然等于i的a的方案数,由&的运算法则:同为1 才为一,所以得出f【i】所包含的所有a相&一定!=0,(因为在i的每一个“1”位,那些a一定是1)。所以这f【i】个数组合的所有方案数均不合法。最终统计答案用总方案数-不和法方案数=合法方案数,所以这里又要用到容斥原理,

ans=总方案数(2^n-1)-相&后的二进制中有一个1+相&后二进制中有两个1-相&后二进制中有三个1……=相&后没有1(即为0)

总结:容斥原理的题感觉都很#人,所以要多做题,善于发现各个方案数重复的那部分。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define mod 1000000007
#define N 3000000
using namespace std;
inline int read()
{int ra,fh;char rx;rx=getchar(),ra=0,fh=1;while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();if(rx=='-')fh=-1,rx=getchar();while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
}
int n,x,dp[N],g[N];
long long f[N];
long long ans=0;
int main()
{scanf("%d",&n);int mx=(1<<20)-1;for(int i=1;i<=n;i++){x=read();dp[x]++;}f[0]=1;for(int i=1;i<=n;i++) f[i]=(f[i-1]<<1)%mod;for(int i=20;i>=1;i--)for(int j=mx;j>=0;j--)if(!(j & (1<<(i-1))))dp[j]+=dp[j|(1<<(i-1))];ans=f[n]-1;for(int i=1;i <= mx;i++){g[i]=g[i>>1]+(1&i);if(g[i]&1) ans=(ans-f[dp[i]]+1+mod)%mod;else ans=(ans+f[dp[i]]-1+mod)%mod;}printf("%lld\n",ans);return 0;
}


这篇关于51nod 1407 与与与与的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/464403

相关文章

【51nod】算法马拉松4 F 移数字 【快速求N!%P】【FFT】

传送门:【51nod】算法马拉松4 F 移数字 涉及知识点:多项式求逆,多项式除法,多点插值,阶乘取模。 对于N!%P,复杂度为 O(N−−√log2N−−√) O(\sqrt N \log^2\sqrt N)。 但常数巨大,和暴力算实际复杂度只相差常数= = 这个是可以扩展到组合数取模的~ my  code: my~~code: #include <stdio.h>#includ

独木舟(51Nod-1432)

题目 n个人,已知每个人体重。独木舟承重固定,每只独木舟最多坐两个人,可以坐一个人或者两个人。显然要求总重量不超过独木舟承重,假设每个人体重也不超过独木舟承重,问最少需要几只独木舟? 输入 第一行包含两个正整数n (0<n<=10000)和m (0<m<=2000000000),表示人数和独木舟的承重。 接下来n行,每行一个正整数,表示每个人的体重。体重不超过1000000000,并且每个人的体

51nod 1847 奇怪的数学题

Description 给出 N,K ,请计算下面这个式子: ∑Ni=1∑Nj=1sgcd(i,j)k 其中,sgcd(i, j)表示(i, j)的所有公约数中第二大的,特殊地,如果gcd(i, j) = 1, 那么sgcd(i, j) = 0。 考虑到答案太大,请输出答案对2^32取模的结果. 1≤N≤109,1≤K≤50 样例解释: 因为gcd(i, j)=1时sgcd(i,j)

51nod-1050 循环最大字段和

N个整数组成的循环序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续的子段和的最大值(循环序列是指n个数围成一个圈,因此需要考虑a[n-1],a[n],a[1],a[2]这样的序列)。当所给的整数均为负数时和为0。 例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。 Input 第1行:整数序列的长

51Nod 1163 最高的奖励(贪心+优先队列 并差集)

题目链接:最高的奖励 题目大意 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是1个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。 Input 第1行:一个数N,表示任务的数量(2 <= N <= 50000) 第2 - N + 1行,每行2个数

51Nod 1376 最长递增子序列的数量(dp+树状数组)

题目链接 最长递增子序列的题做过不少,让求数量的还是第一次,O(n^2)的代码很好写,但数据范围50000,故无情超时,想了很久,总算有所得。 时间: O(nlog(n)) 空间: O(2*n) 思路 O(n^2)的思路中,每次求以第i个数结尾的最大长度和记录总数都要对前i-1个数进行遍历比较,如果能把这个比较过程转化为对前i项对求和,就可以用树状数组或线段数进行求和优化了。 重

51Nod 1022 石子归并 V2 (划分型dp四边形不等式优化)

石子归并以前做过好几次,是经典划分型dp题之一,一直用的O(n3)的正常dp方法,也从未想过该怎么去优化它。 直到昨天做这道题,n的范围由往常的100改为了1000,老方法 一直超时,苦不堪言,搜到有个四边形不等式的优化方法,看帖子,画式子,拉着学长帮忙推导,总算是大概弄明白了一点。 dp(i,j) = min(dp(i,k)+dp(k+1,j)) + w(i,j);(i < j

【TWVRP】基于matlab粒子群算法求解带时间窗的多客户单仓库车辆路径规划问题【含Matlab源码 1407期】

⛄一、获取代码方式 获取代码方式1: 完整代码已上传我的资源: 【TWVRP】基于matalb粒子群算法求解带时间窗的多客户单仓库车辆路径规划问题【含Matlab源码 1407期】 获取代码方式2: 付费专栏Matlab路径规划(初级版) 备注: 点击上面蓝色字体付费专栏Matlab路径规划(初级版),扫描上面二维码,付费29.9元订阅海神之光博客付费专栏Matlab路径规划(初级版),凭支

51nod 1264 线段相交(几何)

1264 线段相交 基准时间限制:1 秒 空间限制:131072 KB 分值: 0  难度:基础题  收藏  关注 给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交)。 如果相交,输出"Yes",否则输出"No"。 Input 第1行:一个数T,表示输入的测试数量(1 <= T <= 1000)第2

51nod 1174 区间中最大的数(RMQ)

1174 区间中最大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0  难度:基础题  收藏  关注 给出一个有N个数的序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,最大的数是多少。 例如: 1 7 6 3 1。i = 1, j = 3,对应的数为7 6 3,最大的数为7。(该问题也被称为RMQ问题)