NOIP2024模拟赛13:拆开未来

写在前面:进制哈希的P不要用998244353会被卡!用131。注意取模为负数的情况!

C-重复

  • 一句话题意:给定字符串 \(S\), 问 \(S\) 的所有子串共有多少种“好的拆分方案”。对于一个字符串 \(S\), 一个划分是好的当且仅当能把 \(S\) 划分成 6 个非空子串 \(a,b,c,d,e,f\), 满足 \(a=b=e, \ c=f\) (一个字符串可能有多种划分方式)

  • 标签:前缀和,思维,散列表(哈希)

  • 简化一下就是要满足 \(AABCAB\).

  • 60分的暴力是对每一个区间枚举开头的 \(A\) 和结尾的 \(B\). (P.S.模数设 \(998244353\) 会被卡!!!)

    const int N=5005;
    const ll P=131;
    ull h[N],p[N];
    char s[N];
    int n; ll ans=0;
    ull get(int l,int r){ return h[r]-h[l-1]*p[r-l+1]; }
    void solve(int l,int r){
    int len=r-l+1;
    F(i,1,len/3) for(int j=1;j<=len/2 && 3*i+2*j<len;++j){
    ull A=get(l,l+i-1),B=get(l+i,l+2*i-1),C=get(l+2*i,l+2*i+j-1),E=get(r-i-j+1,r-j),F=get(r-j+1,r);
    if(A == B && B == E && C == F) ++ans;
    }
    }
    signed main(){
    freopen("c.in","r",stdin); freopen("c.out","w",stdout);
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>(s+1); n=strlen(s+1); p[0]=1;
    F(i,1,n) h[i]=h[i-1]*P+s[i]-'0',p[i]=p[i-1]*P;
    F(l,1,n) F(r,l+5,n) solve(l,r);
    cout<<ans;
    return 0;
    }
  • 但正如邓老师所说,这种拆分方式是“不平衡的”,虽然我们可以用 \(O(1)\) 的时间去检查剩下的位置,但我们却需要花 \(O(N^2)\) 的时间枚举所有的首尾情况。

  • 所以正解我们选择枚举 \(AB\). 枚举 \(A\) 的左端点 \(i\) 和 \(B\) 的右端点 \(j\).

  • 对于 \(AA\), 在固定 \(i\) 的情况下可以用前缀和处理所有贡献。

  • 对于 \(AB\) 和后面那个 \(AB\) 的匹配, 把所有已经扫到过的 \(AB\) 存进一个散列表并统计其个数(\(unorderedmap\) 会 T掉)

  • 两者的贡献相乘即是单次的总贡献。

  • 注意循环的初末条件,\(C\) 不为空(详见代码)

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=r;++i)
#define G(i,r,l) for(int i(r);i>=l;--i)
using namespace std;
using ll = long long;
using ull = unsigned long long;
const int N=5005,mod=1e7+9;
const ll P=131;
ll h[N],p[N];
char s[N];
int n,f[N][N];
ll ans=0;
ull get(int l,int r){ return h[r]-h[l-1]*p[r-l+1]; }
struct node{//AB的散列表
int first[mod],ne[N*N/2],cnt=0;
ll val[N*N/2],dui[N*N/2];
//注意:first的下标肯定小于mod,但由于顺延的原因,散列表的总大小完全可能大于mod , 所以空间开 N*N/2 而不是mod
inline void update(ll x){
ll o = (x%mod+mod)%mod;//把要加入的数用取模得到一个映射
for(int i=first[o];i;i=ne[i]){
if(dui[i]==x){
val[i]++;
return ;
}//对于已存在的数,直接加个数(val)
}
//对于不存在的数,顺次延后新开一个位置(完全同邻接表写法)
ne[++cnt]=first[o];
first[o]=cnt;
dui[cnt]=x;
val[cnt]=1;
return ;
}
inline ll fd(ll x){
ll o = (x%mod+mod)%mod;
for(int i=first[o];i;i=ne[i]){
if(dui[i]==x) return val[i];
}
return 0;
}
}mp;//散列表(充当unordered_map,但更快)
signed main(){
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin>>(s+1); n=strlen(s+1); p[0]=1;
F(i,1,n) h[i]=h[i-1]*P+s[i]-'0'+37,p[i]=p[i-1]*P;//哈希 F(len,1,n){
for(int i=len+1;i+len-1<=n;++i){
int j=i+len-1;
f[i][j]=(get(i-len,i-1)==get(i,j));
}
}
F(i,1,n) F(j,i,n) f[i][j]+=f[i][j-1];//处理 A=A 的前缀和 //枚举AB
for(int j = n-2; j >= 1; j--) { //B的右端点,由于是用AB更新散列表,长度至少要留2,所以 j 从 n-2 开始
//首先是统计答案
for(int i = 2; i < j; i++) {//A的左端点,因为要满足 AAB,所以i从2开始
int rp = min(2 * i - 2, j - 1);
//因为A对称,所以A的长度最大为i-1,所以AA的右端点最大为 2*(i-1)
//同时不能超过 B 的右端点
ans += 1ll * f[i][rp] * mp.fd(get(i, j));//AA的方案数 * AB 的方案数 = AAB的方案数
}
//接着是更新散列表
for(int i = j + 2; i <= n; i++) {
mp.update(get(j + 1, i));//因为下一次的j统计答案时,至少要给C留1的位置,所以起点为 j+1.
}
}
cout<<ans<<"\n";
return 0;
}

NOIP2024模拟赛13:拆开未来的更多相关文章

  1. NOIP2017提高组 模拟赛13(总结)

    NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...

  2. NOIP模拟赛13

    期望得分:100+0+100=200 实际得分:100+5+100=205 T1 空间卡到30M.. n<=2.5*1e7 若x是整除区间[1,n]每个数的最小的数,那么对[1,n]每个数分解质 ...

  3. 小奇模拟赛9.13 by hzwer

    2015年9月13日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿(explo) [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞 ...

  4. NOIP第7场模拟赛题解

    NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...

  5. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  6. [GRYZ]寒假模拟赛

    写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...

  7. CH Round #48 - Streaming #3 (NOIP模拟赛Day1)

    A.数三角形 题目:http://www.contesthunter.org/contest/CH%20Round%20%2348%20-%20Streaming%20%233%20(NOIP模拟赛D ...

  8. 【CJOJ P1957】【NOIP2010冲刺十模拟赛】数字积木

    [NOIP2010冲刺十模拟赛]数字积木 Description 小明有一款新式积木,每个积木上都有一个数,一天小明突发奇想,要是把所有的积木排成一排,所形成的数目最大是多少呢? 你的任务就是读入n个 ...

  9. 52-2018 蓝桥杯省赛 B 组模拟赛(一)java

    最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增.比如 212212 就是一个U型数字,但是 333333, 9898, 567567, 313133131 ...

  10. NOIP2018 模拟赛(二十二)雅礼NOI

    Preface 这次的题目都是NOI+的题,所以大家的分数都有点惨烈. 依靠T1大力骗分水到Rank2 所以想看正解的话看这里吧 A. 「雅礼NOI2018模拟赛(一) Day1」树 看一眼题目感觉十 ...

随机推荐

  1. JAVA——水仙花数问题

    2024/07/12 1.问题 2.错误解法 3.错误分析 4.正确解法 5.其他:关于Java中幂函数的用法 6.参考 1.问题 2.错误解法 import java.util.Scanner; p ...

  2. cnetos7.3离线安装vscode

    1.从官网下载压缩包(话说下载下来解压就直接可以运行了咧,都不需要make) #下载vscode包 访问Visual Studio Code官网 https://code.visualstudio.c ...

  3. navicat远程连接报错

    mysql,2003 can't connect to mysql server on 10038 我们连接远程服务器的mysql,如果出现问题,很大问题会出在服务器的端口和授权问题 # 首先我们通过 ...

  4. 10 Python面向对象编程:类和对象以及和Java的对比

    本篇是 Python 系列教程第 10 篇,更多内容敬请访问我的 Python 合集 这里只介绍类和对象,self.属性.方法.访问控制.类继承.方法重写在后面的文章里介绍 在Python中,类和对象 ...

  5. chrome 被hao123 劫持处理

    打开chrome,就进入baidu.com/xxx,烦人,浏览器被劫持了XXXX 查注册表hao123,删除找到的 进入chrome设置,修改主页新标签页 装杀毒软件,查杀病毒 修改chrome名 等 ...

  6. SpringBoot定时任务实现数据同步

    业务的需求是,通过中台调用api接口获得,设备数据,要求现实设备数据的同步. 方案一:通过轮询接口的方式执行 pullData() 方法实现数据同步 该方式的原理是先清空之前的所有数据,然后重新插入通 ...

  7. 以太坊Rollup方案之 arbitrum(1)

    什么是Rollup? 以太坊的Rollup扩容是一种Layer 2(第二层)扩容解决方案,旨在提高以太坊区块链的交易吞吐量和性能.它通过将大量的交易数据转移到以太坊区块链之外的第二层网络来实现这一目标 ...

  8. PRCV 2023:语言模型与视觉生态如何协同?合合信息瞄准“多模态”技术

    PRCV 2023:语言模型与视觉生态如何协同?合合信息瞄准"多模态"技术 近期,2023年中国模式识别与计算机视觉大会(PRCV)在厦门成功举行.大会由中国计算机学会(CCF). ...

  9. mongo查看服务状态

    转载请注明出处: 查看数据库列表 show dbs 查看当前数据库 db 查看集合列表 show collections 查看数据库的状态 db.stats() 查看集合的状态 db.collecti ...

  10. MySQL linux下安装,配置,免密登录与基本认识

    目录 MySQL卸载 环境 查看是否已安装MySQL 卸载mysql服务 查看是否卸载干净 MySQL安装 查看linux版本 选择MySQL版本 获取mysql官方yum源 rpm安装mysql官方 ...