当前位置: 首页 > news >正文

P3732 [HAOI2017] 供给侧改革 - Link

题意

给一个长度为 \(n\)\(01\) 串串,定义 \(\text{date}(l,r)\) 为起始位置在 \([L,R]\) 之间的这些后缀之中,具有最长公共前缀的两个后缀的最长公共前缀的长度。
\(q\) 次询问 \((L,R)\),表示求 \(ans=\sum_{L\le i<R}\text{data(i,R)}\)

思路

先考虑对于制定的 \(L,R\),如何求 \(\text{data}(L,R)\)
由于字符串随机生成,所以两个相同的字串不会太长。设 \(max\_len=32\),即最长的公共前缀不会超过 \(max\_len\)
对于每个位置 \(i\),求出祂向后 \(j(1\le j\le max\_len)\) 个字符的哈希值,记位 \(h_{i,j}\),求出最小的 \(nt_{i,j}\),满足 \(h_{nt_{i,j},j}=h_{i,j},nt_{i,j}>i\),如果没有,设为 \(n+1\)
在求 \(\text{date}(L,R)\) 时,找到最大的长度 \(l\),满足 \(\min_{L\le i\le R}(nt_{i,l})<=R\),那么 \(\text{data}(L,R)=l\)
对于一次询问 \((L,R)\),从小到大枚举一个长度 \(l\),求出最大的 \(i\),满足 \(nt_{i,l}\le R\),令 \(i'\) 是最大的满足 \(nt_{i',l-1}\le R\) 的位置,那么所有 \(j\in(i,i']\) 的贡献都是 \(l-1\)
这个东西可以用线段树做。
时间复杂度 \(\mathcal O(n\log^2n)\)

代码

存哈希值是用 map 被卡常了,换了 unordered_map
拿下最劣解。

#include<bits/stdc++.h>
using namespace std;
namespace IO{template<typename T>inline void read(T&x){x=0;char c=getchar();bool f=0;while(!isdigit(c)) c=='-'?f=1:0,c=getchar();while(isdigit(c)) x=x*10+c-'0',c=getchar();f?x=-x:0;}template<typename T>inline void write(T x){if(x==0){putchar('0');return ;}x<0?x=-x,putchar('-'):0;short st[50],top=0;while(x) st[++top]=x%10,x/=10;while(top) putchar(st[top--]+'0');}inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}inline void write(char c){putchar(c);}inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
#define ull unsigned long long
const int maxn=100010,maxlen=50;
int n,q,nt[maxn][maxlen];
string s;
class Hash{
private:ull h[maxn],mi[maxn];const ull base=131;
public:void build(string s){mi[0]=1;for(int i=1;i<=100000;i++) mi[i]=mi[i-1]*base;for(int i=0;i<s.size();i++) h[i+1]=h[i]*base+s[i]-'0';}ull query(int l,int r){return h[r]-h[l-1]*mi[r-l+1];}
}h;
unordered_map<ull,int>mp[maxlen];
class Segment_Tree{
private:int t[maxn*4];void insert(int u,int l,int r,int d,int z){if(l>d||r<d) return ;if(l==r){t[u]=z;return ;}int mid=l+r>>1;if(mid>=d) insert(u<<1,l,mid,d,z);else insert(u<<1|1,mid+1,r,d,z);t[u]=min(t[u<<1],t[u<<1|1]);}int query(int u,int l,int r,int ll,int rr,int x){if(l>rr||r<ll) return -1;if(l==r) return l;int mid=l+r>>1;if(t[u<<1|1]<=x) return query(u<<1|1,mid+1,r,ll,rr,x);if(t[u<<1]<=x) return query(u<<1,l,mid,ll,rr,x);return -1;}
public:void init(){memset(t,0x3f,sizeof(t));}void insert(int d,int z){insert(1,1,n,d,z);}int query(int l,int r,int x){return query(1,1,n,l,r,x);}
}t[maxlen];
signed main(){for(int i=1;i<=32;i++) t[i].init();read(n,q,s);h.build(s);for(int i=n;i>=1;i--){nt[i][0]=i;for(int j=1;j<=32;j++) nt[i][j]=n+1;for(int j=1;j<=32;j++){if(i+j-1>n) break;ull ha=h.query(i,i+j-1);if(mp[j][ha]) nt[i][j]=mp[j][ha];mp[j][ha]=i;}}for(int i=1;i<=n;i++) for(int j=1;j<=32;j++) t[j].insert(i,nt[i][j]);for(int i=1;i<=q;i++){int L,R;read(L,R);int ans=0;for(int l=1;l<=32;l++){int w=t[l].query(L,R-1,R);if(w!=-1) ans+=w-L+1;}write(ans),write("\n");}return 0;
}
http://www.jsqmd.com/news/694811/

相关文章:

  • 2026年4月维普降AI全量横评:嘎嘎降AI和率零领先
  • 企业安全自查手册:利用开源工具V2.0对你的泛微、用友、致远OA做一次深度漏洞扫描
  • 2026年B端行业GEO优化服务商市场研究:推荐3家具备成熟服务能力的专业服务商 - 商业小白条
  • Day07-MySQL
  • 计算机毕业设计:Python量化交易管理平台 Django框架 requests爬虫 数据分析 可视化 大数据 大模型(建议收藏)✅
  • 细粒度并行计算架构Squire的设计与优化实践
  • AI数学基础:线性代数、概率论与微积分实战解析
  • Nucleus Co-Op技术解密:单机游戏分屏多人的创新突破与完整实现指南
  • 别再死记硬背SVPWM公式了!用STM32的定时器PWM模式2,手把手教你从Simulink仿真到代码落地
  • 3步轻松配置TTS-Vue桌面语音合成工具完整指南
  • 创建 ext4/xfs 文件系统供容器挂载
  • 别只拿JTAG下载程序了!手把手教你用边界扫描给电路板做‘体检’
  • 别再混淆了!一张图讲清EsKF、IEKF和EsIKF在VIO/SLAM中的区别与联系
  • 如何快速获取Hadoop Windows工具包:winutils完整指南 [特殊字符]
  • 题解:AtCoder AT_awc0003_b Line of Handshakes
  • STM32 DAC输出波形实战避坑:为什么你的正弦波有毛刺?如何优化三角波线性度?
  • 维普AI率工具哪个好?2026年4月8款产品深度对比
  • DNSLog实战指南:三大主流平台特性解析与场景应用
  • 别再死记DH参数了!用MATLAB Robotic Toolbox快速验证你的机器人模型(附工作空间计算代码)
  • Linux下4G/5G模块实战:从AT指令到NetworkManager,手把手搞定蜂窝网络连接
  • 如何从已禁用 iTunes 连接的 iPhone 中恢复数据
  • 题解:AtCoder AT_awc0003_c Bargain Sale Selection
  • AI SoC全芯片DFT实战
  • 别再只用enable password了!思科设备密码安全进阶:配置加密的enable secret与Console口超时
  • 深度强化学习与自然语言理解的融合实践
  • 手写一个分布式RPC框架!
  • AirSim安装报错‘No module named numpy’?一个隐藏的依赖陷阱与解决方案
  • 面试官最爱问的C++服务器项目:TinyWebServer中Epoll与Reactor模式如何协同工作?
  • 如何在 Realme 上恢复已删除的联系人
  • 【电能质量扰动】基于ML和DWT的电能质量扰动分类方法研究(Matlab实现)