题解:P10200 [湖北省选模拟 2024] 花神诞日 / sabzeruz
littlez_meow · · 题解
今年二月份的时候不会做,现在看来觉得自己当时好菜啊。
思路
首先是一个结论,
所以给
这个题意长得很像什么?是不是很像 CSP-S2024 T3?
考虑一样地设状态。设
转移分两种,首先是
其中方括号是艾弗森括号。然后是
初值为
考虑优化。我们对
先考虑后两个转移。需要快速维护满足
然后再是前两个。既然上 trie 树了那也好处理,如果
最后统计答案不能去
时间复杂度
代码
#include<bits/stdc++.h>
#define F(i,a,b) for(int i(a),i##i##end(b);i<=i##i##end;++i)
#define R(i,a,b) for(int i(a),i##i##end(b);i>=i##i##end;--i)
#define File(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout)
#define ll long long
using namespace std;
const int MAXN=2e5+1,MOD=1e9+7;
int n;
ll a[MAXN],k[2];
int rt=1,cnt=1,nxt[MAXN*64][2],s[2][MAXN*64],tag[MAXN*64];
inline void psd(int now){
if(tag[now]&1){
if(nxt[now][0]) s[0][nxt[now][0]]=0,tag[nxt[now][0]]|=1;
if(nxt[now][1]) s[0][nxt[now][1]]=0,tag[nxt[now][1]]|=1;
}
if(tag[now]&2){
if(nxt[now][0]) s[1][nxt[now][0]]=0,tag[nxt[now][0]]|=2;
if(nxt[now][1]) s[1][nxt[now][1]]=0,tag[nxt[now][1]]|=2;
}
tag[now]=0;
return;
}
inline void upd(int now){
(s[0][now]=s[0][nxt[now][0]]+s[0][nxt[now][1]])>=MOD&&(s[0][now]-=MOD);
(s[1][now]=s[1][nxt[now][0]]+s[1][nxt[now][1]])>=MOD&&(s[1][now]-=MOD);
return;
}
void mdf(int&now,int dep,ll v,int val,int id){
if(!now) now=++cnt;
if(dep==-1) return s[id][now]=val,void();
psd(now);
mdf(nxt[now][v>>dep&1],dep-1,v,val,id);
upd(now);
return;
}
int qry(int now,int dep,ll v,bool id){//s[id^1] of v^a[i]>=k[id]
if(!now) return 0;
if(dep==-1) return s[id^1][now];
psd(now);
if(k[id]>>dep&1) return qry(nxt[now][(v>>dep&1)^1],dep-1,v,id);
else{
int ans=s[id^1][nxt[now][(v>>dep&1)^1]]+qry(nxt[now][v>>dep&1],dep-1,v,id);
ans>=MOD&&(ans-=MOD);
return ans;
}
return 0;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>k[0]>>k[1];
F(i,1,n) cin>>a[i];
sort(a+1,a+n+1);
a[0]=1ll<<60;
mdf(rt,60,a[0],1,0),mdf(rt,60,a[0],1,1);
F(i,1,n-1){
int dp0,dp1;
dp0=qry(rt,60,a[i+1],0),dp1=qry(rt,60,a[i+1],1);
if((a[i+1]^a[i])<k[0]) tag[rt]|=1,s[0][rt]=0;
if((a[i+1]^a[i])<k[1]) tag[rt]|=2,s[1][rt]=0;
mdf(rt,60,a[i],dp0,0),mdf(rt,60,a[i],dp1,1);
}
cout<<((s[0][rt]+s[1][rt]-s[0][nxt[rt][1]]-s[1][nxt[rt][1]])%MOD+MOD)%MOD;
return 0;
}