ARC133D Range XOR
ARC133D Range XOR
题目链接:【ARC133D】 Range XOR
非常好数位 dp。
思路
根据异或的前缀和,我们可以把式子化成这样。
然后先去掉
但是这个玩意没有对称性,很蛋疼,先把区间拉平。
然后考虑这个式子多算的部分,发现多算的只有
把
设
最后我们想要求的东西是
由于
这样子还是很不友好,我们观察一下
我们会发现
显然有规律:
可以使用数学归纳法证明,证明比较简单,留给读者自行思考。
如果
我们先把后两位确定下来,接着删除末两位,消除模
剩下的等价求
这里可以考虑先枚举最后两位,如果是
时间复杂度大概是
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=998244353;
const int maxn=65,kL=60;
ll l,r,v;
ll f[maxn][2][2];
ll kB[4]={0,1,3,0};
ll S(ll i,ll n,ll ln,ll m,ll lm,ll v)
{
if(i==-1) return 1;
ll &fs=f[i][ln][lm];
if(~fs) return fs;
fs=0;
for(ll kn=0,vn=(ln?(n>>i&1):1);kn<=vn;kn++)
{
for(ll km=0,vm=(lm?(m>>i&1):1);km<=vm;km++)
{
if((kn^km)==(v>>i&1)) fs=(fs+S(i-1,n,ln&&kn==vn,m,lm&&km==vm,v))%mod;
}
}
return fs;
}
ll bS(ll n,ll m,ll v)
{
memset(f,-1,sizeof(f));
return S(kL-1,n,1,m,1,v);
}
ll S1(ll n,ll m)
{
if(n<0||m<0) return 0;
ll s=0;
for(ll i=0;i<4;i++)
{
for(ll j=0;j<4;j++)
{
ll w=(v^kB[i]^kB[j]);
if(w&3) continue;
ll ci=(n>>2)-((n&3)<i);
ll cj=(m>>2)-((m&3)<j);
s=(s+bS((i&1)?0:ci,(j&1)?0:cj,w>>2)*((i&1)?(ci+1)%mod:1)%mod*((j&1)?(cj+1)%mod:1)%mod)%mod;
}
}
return s;
}
ll S2(ll l,ll r)
{
return ((S1(r,r)-2*S1(l-1,r)+S1(l-1,l-1))%mod+mod)%mod;
}
int main()
{
scanf("%lld%lld%lld",&l,&r,&v);
printf("%lld",(S2(l-1,r)-(v==0)*(r-l+2)%mod+mod)*(mod+1)/2%mod);
}
分类:
Atcoder ARC
, 动态规划/dp / 数位 dp
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现