hdu 6889 数位dp Xor
Posted goto_1600
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 6889 数位dp Xor相关的知识,希望对你有一定的参考价值。
题意:
思路:
数位dp,考虑设计状态,第四个条件很好满足,设计一个flag3为状态位就可以了代表是否已经大于w,flag2,flag3代表是否到达枚举x和y的limit,那么第三个条件怎么设计呢,考虑稍微改变一下柿子,
x
−
y
<
=
k
&
&
y
−
x
<
=
k
x-y<=k~ \\&\\&~y-x<=k~
x−y<=k && y−x<=k 那么就好办了,考虑x-y+k只有
[
−
1
,
2
]
[-1,2]
[−1,2]的情况下,由于前面如果推下来<-1那么永远都不能大于,是无效状态,同时2这个状态位也是多余的,有1就够了,因为后面怎么弄都不会超过这个1.
//#pragma GCC target("avx")
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
// created by myq
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long ll;
#define x first
#define y second
typedef pair<int,int> pii;
const int N = 400010;
const int mod=998244353;
inline int read()
{
int res=0;
int f=1;
char c=getchar();
while(c>'9' ||c<'0')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
res=(res<<3)+(res<<1)+c-'0';
}
return res;
}
ll dp[32][2][2][2][4][4];
int a[32],a1[32];
int b[32],a2[32];
int c[32],k[32];
int d[32],w[32];
int E=1;
ll dfs(int len,int flag1,int flag2,int flag3,int k1,int k2){
if(!len){
return k1>=0 && k2>=0;
}
if(~dp[len][flag1][flag2][flag3][k1+E][k2+E]) return dp[len][flag1][flag2][flag3][k1+E][k2+E];
ll res=0;
int up1=flag1?a[len]:1;
int up2=flag2?b[len]:1;
for(int i=0;i<=up1;i++)
{
for(int j=0;j<=up2;j++){
if(flag3 && (i^j)&&!w[len]) continue;
int kk1=min(k1*2+k[len]+j-i,2);
int kk2=min(k2*2+k[len]+i-j,2);
if(kk1<=-2 || kk2<=-2) continue;
res+=dfs(len-1,flag1&(i==up1),flag2&(j==up2),flag3&((i^j)==w[len]),kk1,kk2);
}
}
return dp[len][flag1][flag2][flag3][k1+E][k2+E]=res;
}
ll solve(int A,int B,int K,int W){
memset(dp,-1,sizeof dp);
for(int i=30;i>=0;i--){
a[i+1]=A>>i&1;
b[i+1]=B>>i&1;
k[i+1]=K>>i&1;
w[i+1]=W>>i&1;
}
return dfs(31,1,1,1,0,0);
}
int main()
{
int T;
cin>>T;
while(T--){
int a,b,k,w;
cin>>a>>b>>k>>w;
cout<<solve(a,b,k,w)<<endl;
}
return 0;
}
/**
* In every life we have some trouble
* When you worry you make it double
* Don't worry,be happy.
**/
以上是关于hdu 6889 数位dp Xor的主要内容,如果未能解决你的问题,请参考以下文章