【BZOJ2728】[HNOI2012]与非 并查集+数位DP
【BZOJ2728】[HNOI2012]与非
Description
.jpg)
Input
输入文件第一行是用空格隔开的四个正整数N,K,L和R,接下来的一行是N个非负整数A1,A2……AN,其含义如上所述。 100%的数据满足K≤60且N≤1000,0<=Ai<=2^k-1,0<=L<=R<=10^18
Output
仅包含一个整数,表示[L,R]内可以被计算出的数的个数
Sample Input
3 4 5
Sample Output
HINT
样例1中,(3 NAND 4) NADN (3 NAND 5) = 1,5 NAND 5 = 2,3和4直接可得。
题解:一开始想用逻辑分析的角度来处理这道题,发现对于本蒟蒻来说实在是处理不了,还是感性理解比较适合我~
我们用一个数nand它本身,就得到了这个数取非,将两个取非的数nand一起自然就是与,有了非和与自然就有了或,有了与,非,或也自然就有了异或,所以只用nand显然是可以表示所有逻辑运算的。
不过这样就能表示所有的数了吗?显然不能,发现如果集合中所有的数的某几位是一样的话,无论怎么运算这几位肯定还是一样的,所以我们只需要统计有多少数的这几位都是一样的就行了。然后我们用并查集处理出有哪些位是一样的,剩下的就交给数位DP就行了(又是INF的细节)。
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
int n,k,tot,s[70];
ll ans,v[1010];
int f[70],mark[70];
int find(int x)
{
return (f[x]==x)?x:(f[x]=find(f[x]));
}
bool check(int a,int b)
{
for(int i=1;i<=n;i++) if(((v[i]>>a-1)^(v[i]>>b-1))&1) return 0;
return 1;
}
ll calc(ll x)
{
if(++x>=(1ll<<k)) return (1ll<<s[k]);
int i;
ans=0;
memset(mark,-1,sizeof(mark));
for(i=k;i;i--)
{
if(x&(1ll<<i-1))
{
if(mark[f[i]]!=1) ans+=1ll<<s[i-1];
if(f[i]==i) mark[i]=1;
if(mark[f[i]]==0) break;
}
else
{
if(f[i]==i) mark[i]=0;
if(mark[f[i]]==1) break;
}
}
return ans;
}
int main()
{
int j;
ll i,l,r;
scanf("%d%d%lld%lld",&n,&k,&l,&r);
for(i=1;i<=n;i++) scanf("%lld",&v[i]);
for(i=1;i<=k;i++)
{
f[i]=i;
for(j=i-1;j;j--) if(check(i,j)&&find(i)!=find(j)) f[f[j]]=f[i];
}
for(i=1;i<=k;i++)
{
s[i]=s[i-1];
if(find(i)==i) s[i]++;
}
printf("%lld",calc(r)-calc(l-1));
return 0;
}
【BZOJ2728】[HNOI2012]与非 并查集+数位DP的更多相关文章
- BZOJ2728 HNOI2012与非(并查集+数位dp)
容易发现x nand x=not x.并且使用这个性质有x and y=not(x nand y)=(x nand y)nand(x nand y).也就是说nand运算可以作为not和and运算使用 ...
- hdu 4514 并查集+树形dp
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- BZOJ_2443_[Usaco2011 Open]奇数度数 _并查集+树形DP
BZOJ_2443_[Usaco2011 Open]奇数度数 _并查集. Description 奶牛们遭到了进攻!在他们的共和国里,有N(1 <= N <=50,000)个城市,由M(1 ...
- poj 1417(并查集+简单dp)
True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2087 Accepted: 640 Descrip ...
- C - BLG POJ - 1417 种类并查集加dp(背包)
思路:刚看这道题感觉什么都不清楚,人物之间的关系一点也看不出来,都不知道怎么写,连并查集都没看出来,但是你可以仔细分析一下,当输入字符串为“yes”的时候,我们设输入的值为x和y,当x为天使是则由题可 ...
- poj1417(带权并查集+背包DP+路径回溯)
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...
- HDU 5575 Discover Water Tank 并查集 树形DP
题意: 有一个水槽,边界的两块板是无穷高的,中间有n-1块隔板(有高度),现有一些条件(i,y,k),表示从左到右数的第i列中,在高度为(y+0.5)的地方是否有水(有水:k = 1),问最多能同时满 ...
- HDU 4514 湫湫系列故事——设计风景线(并查集+树形DP)
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) To ...
- P2700逐个击破(并查集/树形dp)
P2700 逐个击破 题目背景 三大战役的平津战场上,傅作义集团在以北平.天津为中心,东起唐山西至张家口的铁路线上摆起子一字长蛇阵,并企图在溃败时从海上南逃或向西逃窜.为了就地歼敌不让其逃走,老毛同志 ...
随机推荐
- ElasticSearch 分布式集群
1.前言 Elasticsearch用于构建高可用和可扩展的系统.扩展的方式可以是购买更好的服务器(纵向扩展(vertical scale or scaling up))或者购买更多的服务器(横向扩展 ...
- Solr 创建core 从MySql数据库中导入数据
一.创建数据表和数据 在MySql数据中创建mysolrInfo表, 创建字段 id 主键,自动增加 pname :姓名 age :年龄 addtime :增加时间 增加几条数据 二.创建core 当 ...
- 【iOS开发-55】图片轮播案例:scrollView的分页、滚动栏、利用代理控制定时器和Page Control以及多线程问题
案例: (1)用storyboard布局,这里用了三样东西. --UIScrollView就是我们准备存放滚动图片的容器. --Page Control就是控制页数的那几个小点点.能够设置有多少个点. ...
- 最简单的基于FFmpeg的移动端样例:IOS 视频解码器
===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...
- 使用Junit4对web项目进行测试(一)Junit初配置
Junit测试用例不是用来证明你是对的,而是用来证明你没有错 1.功能 -在项目未在浏览器运行之前对获得的结果和预期的结果进行比较调试,减少BUG和发布时的修复工作 2.测试类和代码类应分开存放. ...
- node-表单验证
var http = require('http'); var url = require('url'); var fs = require('fs'); var querystring = requ ...
- UVA10312- Expression Bracketing(Catalan + 递推)
option=com_onlinejudge&Itemid=8&page=show_problem&problem=1253">题目链接 题意:给出一个序列,长 ...
- python ——单下划线(约定)
命名规则: 通常使用小写单词,必要时用下划线分隔增加可读性. 使用一个前导下划线仅用于不打算作为类的公共接口的内部方法和实例变量. Python不强制要求这样; 它取决于程序员是否遵守这个约定. 使用 ...
- linux服务器性能检测工具nmon使用
今天介绍一款linux系统服务器性能检测的工具-nmon及nmon_analyser (生成性能报告的免费工具),亲测可用. 一.介绍 nmon 工具可以帮助在一个屏幕上显示所有重要的性能优化信息,并 ...
- apue学习笔记(第三章 文件I/O)
本章开始讨论UNIX系统,先说明可用的文件I/O函数---打开文件.读写文件等 UNIX系统中的大多数文件I/O只需用到5个函数:open.read.write.lseek以及close open函数 ...