bzoj 2728 与非 【找规律】 【位运算】 【数位dp】

原创 2015年11月20日 23:18:17

通过与非运算可以组合出and和not,然后and和not可以组合所有的逻辑运算。

所以只要有可能,没有表示不出来的数。但是如果所有数都满足st[i]=st[j] 那么这两位无论如何都相等。

并查集维护所有相等的类别,数位dp

还是不太熟练。

01数位dp的本质是枚举所有的非0位,假设它是0,更新答案,然后把它设为1,求之后的答案。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>

#define ll long long
#define inf 1e9
#define eps 1e-10
#define md
#define N 100010
using namespace std;
int mark[N],fa[N];
ll a[N];
bool vis[N];
int K;
int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
int getnum(int x)
{
	memset(vis,0,sizeof(vis));
	for (int i=x;i>=0;i--) vis[find(i)]=1;
	//for (int i=0;i<=x;i++) printf("%d %d  ",fa[i],vis[i]); 
	int ans=0;
	for (int i=0;i<=x;i++) ans+=vis[i];
	return ans;
}
	
ll dp(ll x)
{
	if (x<0) return 0;
	memset(mark,-1,sizeof(mark));
	ll ans=0; int t=getnum(K-1); //printf("t %d\n",t);
	if ((x>>K)) return 1ll<<t;
	for (int k=K-1;k>=0;k--)
	{
		int f=find(k);
		if ((x>>k)&1)
		{
			if (mark[f]==1) continue;
			if (mark[f]==-1)
			{
				mark[f]=1; t--;
				ans+=(1ll<<t);
			}
			else if (mark[f]==0)
			{
				ans+=(1ll<<t);
				return ans;
			}
			if ((!k)&&mark[f]==1) ans++;
		}
		else
		{
			if (mark[f]==-1)
			{
				mark[f]=0; t--;
			}
			else if (mark[f]==1) return ans;
			if ((!k)&&mark[f]==0) ans++;
		}
	}
	return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("data.in","r",stdin); //freopen("data.out","w",stdout);
#endif
	int n; ll l,r;
	scanf("%d%d%lld%lld",&n,&K,&l,&r);
	for (int i=1;i<=n;i++)
	  scanf("%lld",&a[i]);
	for (int i=0;i<K;i++) fa[i]=i;
	for (int i=0;i<K;i++)
	  for (int j=i+1;j<K;j++)
	  {
	  	bool bo=1;
	  	for (int k=1;k<=n;k++)
	  	  if (((a[k]>>i)&1)!=((a[k]>>j)&1))
	  	  {
	  	  	bo=0;
	  	  	break;
	  	  }
	  	if (bo)
	  	{
	  		int f1=find(i),f2=find(j);
	  		if (f1!=f2) fa[f1]=f2;
	  	}
	  }
	//printf("%lld %lld\n",dp(r),dp(l-1));
	printf("%lld\n",dp(r)-dp(l-1));
	return 0;
}
	

【数位DP】BZOJ3780数字统计

Time Limit: 10 Sec Memory Limit: 128 MB Description 小A正在研究一些数字统计问题。有一天他突然看到了一个这样的问题: 将[L..R][L.....
  • cqbztsy
  • cqbztsy
  • 2016年02月26日 12:20
  • 683

BZOJ-1228 E&D 博弈SG+找啊找啊找规律

讨厌博弈,找规律找半天还是错的.... 1228: [SDOI2009]E&D Time Limit: 10 Sec Memory Limit: 162 MB Submit: 666 Solv...
  • DaD3zZ
  • DaD3zZ
  • 2016年03月16日 17:36
  • 431

数位dp入门详解

基础篇 数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数。所谓数位dp,字面意思就是在数位上进行dp咯。数位还算是比较好听的名字,数位的含义:一个数有个位、十位...
  • CillyB
  • CillyB
  • 2017年02月19日 23:07
  • 1783

[bzoj3679]数字之积

题目大意一个数x各个数位上的数之积记为f(x) 求[L,R)中满足0 < f(x)
  • WorldWide_D
  • WorldWide_D
  • 2016年12月08日 15:41
  • 394

【数位dp】(涉及到处理前导0问题)

数位dp记忆化搜索中,深搜计算dp值必先经过0-0-0 这条递归途径, 如果前导0对答案不影响那么无所谓,但是影响答案那么需要记录处理。 问题来源比较奇特,我理解错了SPOJ - BALNUM的题意...
  • qq_33199236
  • qq_33199236
  • 2017年05月24日 19:52
  • 311

数位dp总结 之 从入门到模板

for(int i=le;i
  • wust_zzwh
  • wust_zzwh
  • 2016年08月03日 14:37
  • 16482

【BZOJ1833】【ZJOI2010】数字计数 数位DP

然而并没有DP。 题解: [1,R]的答案减去[1,L]的答案。 对于一个数 X ,求 [1,X] 的答案,我是先处理出 [1,999……9] 的答案(那个999……9 然后按位往下扫,计算最...
  • Vmurder
  • Vmurder
  • 2015年06月10日 17:54
  • 875

数位DP学习小结

一、学习心得体会 问题描述: 一般体现为,定义某种性质K,问某区间内具有K性质的数的个数 往往给的区间会很大,对区间内的每个数进行判断显然会超时 于是数位DP登场 数位DP,顾名思义,是对数字的每一位...
  • tomorrowtodie
  • tomorrowtodie
  • 2016年08月06日 21:03
  • 1382

HDU2089 不要62(数位DP入门经典题目)

昨天做了一道很奇怪的数字题,不知道怎么做,今天才知道是数位DP ……我来学习学习。 传送门 大意:给定区间[n,m][n,m],求在n到m中没有“62“或“4“的数的个数。如62315包含62,8...
  • geng4512
  • geng4512
  • 2015年08月24日 20:48
  • 1195

[jzoj]3735. 【Usaco2014Open银组】里程计(odometer) (经典数位DP+详细分析)

https://jzoj.net/senior/#main/show/3735Problem:求[x..y][x..y]中的有趣数.有趣数的定义如下:若一个数字至少有一半以上的数位上拥有相同的数字,则...
  • Algor_pro_king_John
  • Algor_pro_king_John
  • 2017年07月30日 21:25
  • 265
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bzoj 2728 与非 【找规律】 【位运算】 【数位dp】
举报原因:
原因补充:

(最多只允许输入30个字)