传送门
文章目录
- 题意:
- 思路:
题意:
思路:
考虑数位dpdpdp,设计状态f[pos][flag1][flag2][flag3][flag4]f[pos][flag1][flag2][flag3][flag4]f[pos][flag1][flag2][flag3][flag4],其中flag1:x≥Lxflag2:y≤Rx,flag3:z≥Ly,flag4:w≤Ryflag1:x\ge L_xflag2:y\le R_x,flag3:z\ge L_y,flag4:w\le R_yflag1:x≥Lxflag2:y≤Rx,flag3:z≥Ly,flag4:w≤Ry,控制一下上下界即可。
但是可能会有重复的情况,比如当前i,ji,ji,j都为111的时候,那么答案当前位也是111,此时只有一种情况。当i&j=0i\And j=0i&j=0时,会有三种情况(0,0),(1,0),(0,1)(0,0),(1,0),(0,1)(0,0),(1,0),(0,1),这个时候答案的当前位都是111,我们对这三种情况取一个maxmaxmax即可,因为有一种情况肯定包含了其他的情况。
所以直接套个板子即可。
// Problem: #6274. 数字
// Contest: LibreOJ
// URL: https://loj.ac/p/6274
// Memory Limit: 512 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=110,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;LL t,l1,l2,r1,r2;
int L1[N],L2[N],R1[N],R2[N],T[N];
LL f[N][2][2][2][2];
//flag1:>=l1 flag2<=r1 flag3>=l2 flag4<=r2LL dp(int pos,int flag1,int flag2,int flag3,int flag4) {if(pos==-1) return 1;if(f[pos][flag1][flag2][flag3][flag4]!=-1) return f[pos][flag1][flag2][flag3][flag4];int x=flag1? 0:L1[pos];int y=flag2? 1:R1[pos];int z=flag3? 0:L2[pos];int w=flag4? 1:R2[pos];LL ans1=0,ans2=0;for(int i=x;i<=y;i++) {for(int j=z;j<=w;j++) {if((i|j)!=T[pos]) continue;if((i&j)==0) ans1=max(ans1,dp(pos-1,flag1||i>x,flag2||i<y,flag3||j>z,flag4||j<w));else ans2+=dp(pos-1,flag1||i>x,flag2||i<y,flag3||j>z,flag4||j<w);}}return f[pos][flag1][flag2][flag3][flag4]=ans1+ans2;
}LL solve() {memset(f,-1,sizeof(f));for(int i=60;i>=0;i--) {L1[i]=l1>>i&1;L2[i]=l2>>i&1;R1[i]=r1>>i&1;R2[i]=r2>>i&1;T[i]=t>>i&1;}return dp(60,0,0,0,0);
}int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cin>>t>>l1>>r1>>l2>>r2;printf("%lld\n",solve());return 0;
}
/**/