标签:
dp,字典树。
dp递推式很容易知道。dp[i]=max{dp[j]+1} a[j]^..^a[i]<=X,并且[j,i]长度不能超过L。
但是暴力来复杂度极高,所以需要用字典树维护这个东西。将前缀异或和插入到字典树中,然后不断维护a[i]位置之前L个前缀异或和就好了。
跑了405ms,第一次排到第一,有点激动~~~
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0;while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar(); } } const LL mod=(LL)268435456; const int maxn=100010; LL a[maxn],X,P,Q; int T,n,L,dp[maxn],h; struct Node { int cnt,mx,nx[2]; }s[33*maxn]; int sz; bool fail,f[maxn]; int add() { s[sz].mx=0; s[sz].cnt=0; s[sz].nx[0]=s[sz].nx[1]=-1; sz++; return sz-1; } void Delete(LL num) { int p=0; for(int i=31;i>=0;i--) { int x; LL g=(LL)(1<<i); if(num&g) x=1; else x=0; int t=p; p=s[p].nx[x]; s[p].cnt--; if(s[p].cnt==0) { s[t].nx[x]=-1; return; } } } void Insert(LL num,int val) { int p=0; for(int i=31;i>=0;i--) { int x; LL g=(LL)(1<<i); if(num&g) x=1; else x=0; if(s[p].nx[x]==-1) s[p].nx[x]=add(); p=s[p].nx[x]; s[p].cnt++; s[p].mx=max(s[p].mx,val); } } void Find(LL num) { int p=0; for(int i=31;i>=0;i--) { int x; LL g=(LL)(1<<i); if(num&g) x=1; else x=0; int y; if(X&g) y=1; else y=0; if(y==0) { p=s[p].nx[x]; if(p==-1) return; if(i==0) h=max(h,s[p].mx),fail=0; } else { if(s[p].nx[x]!=-1) h=max(h,s[s[p].nx[x]].mx),fail=0; p=s[p].nx[x^1]; if(p==-1) return; if(i==0) h=max(h,s[p].mx),fail=0; } } } int main() { scanf("%d",&T); while(T--) { scanf("%d%lld%d",&n,&X,&L); scanf("%lld%lld%lld",&a[1],&P,&Q); for(int i=2;i<=n;i++) a[i]=(a[i-1]*P%mod+Q)%mod; sz=0; s[sz].cnt=0; s[sz].nx[0]=s[sz].nx[1]=-1; sz++; for(int i=1;i<=n;i++) f[i]=0; for(int i=1;i<=n;i++) { if(i-L-1>=1&&f[i-L-1] ) Delete(a[i-L-1]); dp[i]=0; a[i]=a[i]^a[i-1]; if(a[i]<=X) dp[i]=1; h=0; fail=1; Find(a[i]); if(fail==0) dp[i]=h+1; if(dp[i]!=0) { Insert(a[i],dp[i]); f[i]=1; } } printf("%d\n",dp[n]); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zufezzt/p/5789757.html