$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-;
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 = ;while(!isdigit(c)) c = getchar();
while(isdigit(c)) { x = x * + c - ''; c = getchar(); }
} const LL mod=(LL);
const int maxn=;
LL a[maxn],X,P,Q;
int T,n,L,dp[maxn],h;
struct Node { int cnt,mx,nx[]; }s[*maxn];
int sz; bool fail,f[maxn]; int add()
{
s[sz].mx=; s[sz].cnt=;
s[sz].nx[]=s[sz].nx[]=-; sz++;
return sz-;
} void Delete(LL num)
{
int p=;
for(int i=;i>=;i--)
{
int x; LL g=(LL)(<<i); if(num&g) x=; else x=;
int t=p; p=s[p].nx[x]; s[p].cnt--;
if(s[p].cnt==) { s[t].nx[x]=-; return; }
}
} void Insert(LL num,int val)
{
int p=;
for(int i=;i>=;i--)
{
int x; LL g=(LL)(<<i); if(num&g) x=; else x=;
if(s[p].nx[x]==-) 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=;
for(int i=;i>=;i--)
{
int x; LL g=(LL)(<<i); if(num&g) x=; else x=;
int y; if(X&g) y=; else y=; if(y==)
{
p=s[p].nx[x]; if(p==-) return;
if(i==) h=max(h,s[p].mx),fail=;
}
else
{
if(s[p].nx[x]!=-) h=max(h,s[s[p].nx[x]].mx),fail=;
p=s[p].nx[x^]; if(p==-) return;
if(i==) h=max(h,s[p].mx),fail=;
}
}
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%lld%d",&n,&X,&L);
scanf("%lld%lld%lld",&a[],&P,&Q);
for(int i=;i<=n;i++) a[i]=(a[i-]*P%mod+Q)%mod; sz=; s[sz].cnt=; s[sz].nx[]=s[sz].nx[]=-; sz++; for(int i=;i<=n;i++) f[i]=;
for(int i=;i<=n;i++)
{
if(i-L->=&&f[i-L-] ) Delete(a[i-L-]);
dp[i]=; a[i]=a[i]^a[i-]; if(a[i]<=X) dp[i]=;
h=; fail=; Find(a[i]); if(fail==) dp[i]=h+;
if(dp[i]!=) { Insert(a[i],dp[i]); f[i]=; }
} printf("%d\n",dp[n]);
}
return ;
}

HDU 5845 Best Division的更多相关文章

  1. 【HDU - 5845】Best Division(xor-trie、01字典树、dp)

    BUPT2017 wintertraining(15) #7E 题意 把数组A划分为k个区间,每个区间不超过L长度,每一个区间异或和之和为S.现在求:S不超过X,区间个数的最大值. 且A是这样给你的: ...

  2. 【HDU】3480 Division

    http://acm.hdu.edu.cn/showproblem.php?pid=3480 题意:一个n个元素的集合S要求分成m个子集且子集并为S,要求$\sum_{S_i} (MAX-MIN)^2 ...

  3. 【HDU 6036】Division Game (NTT+数学)

    多校1 1004 HDU-6036 Division Game 题意 有k堆石头(0~k-1),每堆n个.\(n=\prod_{i=0}^{m}p_i^{e_i}\).\(0\le m,k \le 1 ...

  4. hdu 3718 Different Division

    Different Division Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  5. hdu 3480 Division(斜率优化DP)

    题目链接:hdu 3480 Division 题意: 给你一个有n个数的集合S,现在让你选出m个子集合,使这m个子集合并起来为S,并且每个集合的(max-min)2 之和要最小. 题解: 运用贪心的思 ...

  6. HDU 6036 - Division Game | 2017 Multi-University Training Contest 1

    /* HDU 6036 - Division Game [ 组合数学,NTT ] | 2017 Multi-University Training Contest 1 题意: k堆石子围成一个圈,数量 ...

  7. HDU 6036 Division Game

    HDU 6036 Division Game 考虑每堆石头最多操作 $ \sum e $ 次,考虑设 $ f(x) $ 表示某一堆石头(最开始都是一样的)操作 $ x $ 次后变成了 $ 1 $ 的方 ...

  8. hdu 1034 (preprocess optimization, property of division to avoid if, decreasing order process) 分类: hdoj 2015-06-16 13:32 39人阅读 评论(0) 收藏

    IMO, version 1 better than version 2, version 2 better than version 3. make some preprocess to make ...

  9. HDU 3480 Division(斜率优化+二维DP)

    Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others) Tota ...

随机推荐

  1. 使用CATransformLayer制作3D图像和动画

    之前我们讲过可以用CALayer搭配CATransform3D来实现将View做3D旋转, 今天我们再看一个3D的新东西 CATransformLayer, 看名字就知道这个layer跟旋转有关, 那 ...

  2. Ionic2系列——在Ionic2中使用高德地图

    之前讲过了如何在Ionic2中使用第三方库,因为第三方库必须针对TypeScript提供相应的声明文件——即d.ts文件,才能被TypeScript正确识别并编译.好在大多数的第三方库已经有了定义文件 ...

  3. 第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据

    第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据 学习要点: 1.JSON语法 2.解析和序列化 前两章我们探讨了XML的结构化数据,但开发人员还是觉得这 ...

  4. MATLAB ' : ' 官方解释

    1.冒号的作用 产生矢量,阵列标注以及for-loop迭代子 2.描述 冒号是MATLAB中最有用的操作符之一.它使用下述规则来创建有规则的空间矢量: j:k is the same as [j,j+ ...

  5. W: http://archive.ubuntukylin.com:10006/ubuntukylin/dists/xenial/InRelease: Signature by key 6CE35A4EBAB676094476BE7CD259B7555E1D3C58 uses weak digest algorithm (SHA1)

    新装ubuntukylin 16.04,sudo apt-get update 时遇到如下问题:   Hit:1 http://archive.ubuntukylin.com:10006/ubuntu ...

  6. EXCEL 数字统一转换成文本

    将excel中的数字统一转换成文本形式.即添加‘. 1.点击数据-分列. 2.分隔符号-下一步. 3.选择文本识别符号,如“‘”分号. 4. 选中文本-完成.

  7. Java Calendar日历类的使用

    Calendar cal = Calendar.getInstance(); // 当前年 int year = cal.get(Calendar.YEAR); // 当前月 int month = ...

  8. Tiny6410之NAND FLASH驱动

    一.NAND FLASH的特点 S3C6410的NAND FLASH控制器有如下特点 1.自导入模式:复位后,引导代码被送入到8KB的STEPPINGSTONE中,引导代码移动完毕,引导代码将在STE ...

  9. Centos 7 系统安装完毕修改网卡名为eth0

    从CentOS/RHEL7起,可预见的命名规则变成了默认.这一规则,接口名称被自动基于固件,拓扑结构和位置信息来确定.现在,即使添加或移除网络设备,接口名称仍然保持固定,而无需重新枚举,和坏掉的硬件可 ...

  10. IOS开发调整UILabel的行间距

    CGFloat heih = 20;   NSString * cLabelString = @"这是测试UILabel行间距的text.这是测试UILabel行间距的text.n 这是测试 ...