【题解】HDU5845 Best Division (trie树)
【题解】HDU5845 Best Division (trie树)
题意:给定你一个序列(三个参数来根),然后请你划分子段。在每段子段长度小于等于\(L\)且子段的异或和\(\le x\)的情况下最大化分出子段的个数
区间/子段/序列这种东西一大性质就是右端点之后与前面无关。
\(dp(i)\)表示上一个右端点是\(i\)且前面分出来的子段都满足条件的最多子段个数。
直接转移\(O(n^2)\)考虑优化这个东西,子段转前缀和是应该记起来的套路,现在问题就是变成查询两个前缀和的异或值是否满足条件。
先不考虑\(L\)的限制
处理两者异或的数据结构=trie树,于是可以建立一颗01trie,trie的叶子节点可以表示一个值,建立trie输入的字符串就是他对应位置的前缀和。
考虑假如已经有了一个trie树了,在trie树上查询的实质是生成一个新的数。我们可以在生成这个数的时候根据该当前生成位上的新生成的那个数能否为\(1\),以及\(x\)是否为\(1\)讨论一下一个节点子树最大值。
查询子树最大值可以直接线段树+dfs序,但这是数据结构学傻的表现。可以发现trie树树高是\(\log n\)的,直接在插入的时候暴力跳父亲更新父亲的值即可。
考虑\(L\)的限制,这个限制就相当于要让这个trie树支持删除操作,可以每个节点套一个multiset,但这是stl用傻了的表现。可以发现dp数组的值是不降的(这里其实存疑),所以可以直接删。
复杂度\(O(n\log n)\)
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(!isdigit(c))f|=c==45,c=getchar();
while(isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
const int mod=(1<<28)-1;
struct E{
int son[2],Max,cnt;
inline void clear(){memset(son,0,sizeof son);Max=0;cnt=0;}
inline int&operator[](int x){return son[x];}
inline void upd(const int&val,const int&tag){
if(tag==1){
if(Max<val) Max=val,cnt=1;
else if(Max==val) ++cnt;
}
else {
if(Max==val) --cnt;
if(cnt==0) Max=0;
}
}
}e[maxn*28];
int sum[maxn],dp[maxn],cnt,n,x,L,p,q;
inline void insert(const int&x,const int&val){
int now=0;
for(int t=27;~t;--t){
int g=x>>t&1;
if(!e[now][g]) e[now][g]=++cnt,e[cnt].clear();
now=e[now][g];
e[now].upd(val,1);
}
}
inline void Delete(const int&x,const int&val){
int now=0;
for(int t=27;~t;--t){
int g=x>>t&1;
now=e[now][g];
e[now].upd(val,-1);
}
}
inline int que(const int&s,const int&x){
int ret=-1,now=0;
for(int t=27;~t;--t){
int g=s>>t&1;
if(x>>t&1){
if(e[now][g]) ret=max(ret,e[e[now][g]].Max);
if(e[now][g^1]) now=e[now][g^1];
else return ret;
}
else{
if(e[now][g]) now=e[now][g];
else return ret;
}
}
ret=max(ret,e[now].Max);
return ret;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
#endif
int T=qr();
while(T--){
n=qr(); x=qr(); L=qr();
sum[1]=qr(); p=qr(); q=qr();
memset(e,0,sizeof e);
e[cnt=0].clear();
for(int t=2;t<=n;++t) sum[t]=(1ll*sum[t-1]*p+q)&mod;
for(int t=2;t<=n;++t) sum[t]^=sum[t-1];
memset(dp,-1,sizeof dp);
insert(0,0); dp[0]=0;
for(int t=1,l=t-L-1,k;t<=n;++t,++l){
if(l>=0) if(dp[l]>=0) Delete(sum[l],dp[l]);
k=que(sum[t],x);
if(k>=0) dp[t]=k+1,insert(sum[t],dp[t]);
}
printf("%d\n",dp[n]==-1?0:dp[n]);
}
return 0;
}
【题解】HDU5845 Best Division (trie树)的更多相关文章
- 【题解】P4585 [FJOI2015]火星商店问题(线段树套Trie树)
[题解]P4585 [FJOI2015]火星商店问题(线段树套Trie树) 语文没学好不要写省选题面!!!! 题目大意: 有\(n\)个集合,每个集合有个任意时刻都可用的初始元素.现在有\(m\)个操 ...
- Trie树(字典树)-题解 P2580 【于是他错误的点名开始了】
此题可以用STL中的map做,但是了解一下Trie树这个数据结构也是必须的. Trie树(又称字典树)有以下特点: 根节点不包含字符,除它之外的每一个节点都包含一个字符. 从根节点到某一节点,路径上经 ...
- 【BZOJ3439】Kpm的MC密码 trie树+主席树
Description 背景 想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的...),于是乎,他现在理所当然地忘记了密码,只能来解答那些神奇的身 ...
- hiho #1014 : Trie树
#1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助, ...
- [POJ] #1002# 487-3279 : 桶排序/字典树(Trie树)/快速排序
一. 题目 487-3279 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 274040 Accepted: 48891 ...
- HDU1247 - Hat’s Words(Trie树)
题目大意 给定一些单词,要求你把所有的帽子单词找出来,如果某个单词恰好由另外两个单词连接而成,那么它就是帽子单词 题解 先把所有单词插入到Trie树,然后判断每个单词是不是帽子单词,做法就是:对于第i ...
- HDU1671 - Phone List(Trie树)
题目大意 给定一些电话号码,判断是否有电话号码是其他电话号码的前缀 题解 裸Trie树嘛~~~~只需要一个插入过程即可,假设X是Y的前缀,在插入的过程中有两种情况,X在Y之前插入,那么在插入Y的时候经 ...
- HDU1075 - What Are You Talking About(Trie树)
题目大意 给定一些火星文单词以及对应的英语单词,然后给你一些火星文,要求你翻译成对应的英文 题解 第一次写Trie树! 把所有火星文单词插入到Trie树中,并且每个火星文单词结尾的节点记录相应英文单词 ...
- 统计难题(trie树)
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)Total Submi ...
随机推荐
- part10.3-字符驱动访问揭秘
- hdu 2892 area (圆与多边形交面积)
Problem - 2892 这道题的做法是以圆心为原点,对多边形进行三角剖分.题目描述中,多边形的可能是顺时针或者是逆时针给出,不过在我的做法里,是用有向面积来计算的,和常见的多边形面积的求法类似, ...
- 解析xml的方式
1.DOM 理论:将标记文档语言一次性加载进内存,在内存中形成DOM树. 优点:操作方便,可以对文档进行CRUD(增删改查)操作,适用于服务端操作 缺点:占内存,不适用与手机,智能家居等内存容量小的设 ...
- phpstorm 里能做git的命令行操作吗?
在VCS菜单下面有 GIT -> Branches 然后会弹出branch菜单,后面怎么操作应该不需要解释吧,所有的branch都列出来自己选 在Tools菜单下面有Open Terminal. ...
- Python--day62--Django安装,配置,web请求流程,views.py总结
1,安装Django 2,创建Django项目: 3,配置Django项目 1.settinngs.py文件 1.templates文件夹的位置 2.静态文件 1,STATIC_URL ----- ...
- pycharm下的多个python版本共存(一)
经历过IDLE,anaconda,和pycharn的编程环境,并进行了一段时间的项目编程后,决定使用pycharm作为以后的工作环境. 一方面因为项目组其他人推荐,另一方面在使用过程中比较顺手.当然很 ...
- win2d 画出好看的图形
本文告诉大家,win2d 不需要从零开始做,以前做出来的很多库其实只需要做很小修改就可以做出好看的效果,而且用在 UWP 上.本文修改原先 大神写的 GDI 图形到 win2d 上,而且可以运行起来 ...
- Python--day38--多进程的方法属性总结
多进程的方法属性:
- 【9307】&【a303】过河卒(NOIP2002)
Time Limit: 10 second Memory Limit: 2 MB 问题描述 如图,A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右. 同时在棋盘上的任一点有一个对方 ...
- es6—变量的解构赋值
数组的解构赋值 ]]]]]]] = []}} = {}} = {}})]: first]: last} = arr} = {}) {}))}))}) {}))}))].]]]])})] }}} = { ...