LOJ2303 「NOI2017」蚯蚓排队
「NOI2017」蚯蚓排队
题目描述
蚯蚓幼儿园有$n$只蚯蚓。幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演。
所有蚯蚓用从$1$到$n$的连续正整数编号。每只蚯蚓的长度可以用一个正整数表示,根据入园要求,所有蚯蚓的长度都不超过$6$。神刀手希望这些蚯蚓排成若干个队伍,初始时,每只蚯蚓各自排成一个仅有一只蚯蚓的队伍,该蚯蚓既在队首,也在队尾。
神刀手将会依次进行$m$次操作,每个操作都是以下三种操作中的一种:
给出$i$和$j$,令$i$号蚯蚓与$j$号蚯蚓所在的两个队伍合并为一个队伍,具体来说,令$j$号蚯蚓紧挨在$i$号蚯蚓之后,其余蚯蚓保持队伍的前后关系不变。
给出$i$,令$i$号蚯蚓与紧挨其后的一只蚯蚓分离为两个队伍,具体来说,在分离之后,$i$号蚯蚓在其中一个队伍的队尾,原本紧挨其后的那一只蚯蚓在另一个队伍的队首,其余蚯蚓保持队伍的前后关系不变。
给出一个正整数$k$和一个长度至少为$k$的数字串$s$,对于$s$的每个长度为$k$的连续子串$t$(这样的子串共有$|s| - k + 1$ 个,其中$|s|$为$s$的长度),定义函数$f(t)$,询问所有这些$f(t)$的乘积对$998244353$取模后的结果。其中$f(t)$的定义如下:
对于当前的蚯蚓队伍,定义某个蚯蚓的向后$k$数字串为:从该蚯蚓出发,沿队伍的向后方向,寻找最近的$k$只蚯蚓(包括其自身),将这些蚯蚓的长度视作字符连接而成的数字串;如果这样找到的蚯蚓不足$k$只,则其没有向后$k$数字串。例如蚯蚓的队伍为$10$号蚯蚓在队首,其后是$22$号蚯蚓,其后是$3$号蚯蚓(为队尾),这些蚯蚓的长度分别为$4$、$5$、$6$,则$10$号蚯蚓的向后$3$数字串 为456,$22$号蚯蚓没有向后$3$数字串,但其向后$2$数字串为56,其向后$1$数字串为5。
而$f(t)$表示所有蚯蚓中,向后$k$数字串恰好为$t$的蚯蚓只数。
输入输出格式
输入格式:
输入文件的第一行有两个正整数$n,m$ ,分别表示蚯蚓的只数与操作次数。
第二行包含$n$个不超过$6$的正整数,依次表示编号为$1, 2, \dots , n$的蚯蚓的长度。
接下来$m$行,每行表示一个操作。每个操作的格式可以为:
1 i j$(1 \leqslant i, j \leqslant n)$表示:令$i$号与$j$号蚯蚓所在的两个队伍合并为一个队伍,新队伍中,$j$号蚯蚓紧挨在$i$号蚯蚓之后。保证在此操作之前,$i$ 号蚯蚓在某个队伍的队尾,$j$号蚯蚓在某个队伍的队首,且两只蚯蚓不在同一个队伍中。2 i$(1 \leqslant i \leqslant n)$表示:令$i$号蚯蚓与紧挨其后一个蚯蚓分离为两个队伍。保证在此操作之前,$i$号蚯蚓不是某个队伍的队尾。3 s k($k$为正整数,$s$为一个长度至少为$k$的数字串)表示:询问$s$的每个长度为$k$的子串$t$的$f(t)$的乘积,对$998244353$取模的结果。$f(t)$的定义见题目描述。
同一行输入的相邻两个元素之间,用恰好一个空格隔开。
输入文件可能较大,请不要使用过于缓慢的读入方式。
输出格式:
依次对于每个形如3 s k的操作,输出一行,仅包含一个整数,表示询问的结果。
输入输出样例
复制
5 9
3 1 3 5 3
3 333135 2
3 333135 1
1 1 3
1 2 5
1 3 2
1 5 4
3 333135 2
3 333135 1
3 333135 3
复制
2 10
6 6
3 666666 1
1 1 2
3 666666 2
3 666666 4
3 666666666666666666666666666666 1
2 1
1 2 1
3 666666 2
3 666666 4
3 666666666666666666666666666666 1
说明
【子任务】
保证$n \leqslant 2 \times 10^5,\ m \leqslant 5 \times 10^5,\ k \leqslant 50$。
设$\Sigma |S|$为某个输入文件中所有询问的 s 的长度总和,则$\Sigma |S| \leqslant 10^7$。
设$c$为某个输入文件中形如2 i的操作的次数,则$c \leqslant 10^3$ 。
每个测试点的详细信息见下表:

题解
\(k\le 50\),那么变动的量也很少,直接用hash表维护长度和字符串hash值就行了。
至于蚯蚓,使用链表维护即可。
我不开O2就TLE最后一个点,2015ms。毒瘤出题人卡常数。
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef unsigned long long ull;
co int MAX=222222,MOD=998244353,base=233;
char ch[10000010];
ull pw[MAX];
int next[MAX],last[MAX],a[MAX];
int n,m;
co int mod=19260817;
struct Hash_Table{
int h[mod],cnt;
struct Line{int len,next,w;ull s;}e[10000000];
void add(int len,ull s,int w){
for(rg int i=h[s%mod];i;i=e[i].next)
if(e[i].len==len&&e[i].s==s)
return (e[i].w+=w)%=MOD,void();
e[++cnt]=(Line){len,h[s%mod],w,s},h[s%mod]=cnt;
}
int query(int len,ull s){
for(rg int i=h[s%mod];i;i=e[i].next)
if(e[i].len==len&&e[i].s==s) return e[i].w;
return 0;
}
}hash;
void link(int x,int y){
next[x]=y,last[y]=x;
ull sx=0;
for(int i=x,lx=1;i&&lx<=49;i=last[i],++lx){
sx+=a[i]*pw[lx-1];
ull sy=sx;
for(int j=y,ly=lx+1;j&&ly<=50;j=next[j],++ly) sy=sy*base+a[j],hash.add(ly,sy,1);
}
}
void cut(int x){
int y=next[x];
ull sx=0;
for(rg int i=x,lx=1;i&&lx<=49;i=last[i],++lx){
sx+=a[i]*pw[lx-1];
ull sy=sx;
for(rg int j=y,ly=lx+1;j&&ly<=50;j=next[j],++ly) sy=sy*base+a[j],hash.add(ly,sy,MOD-1);
}
next[x]=last[y]=0;
}
int query(int len){
int l=strlen(ch+1),ans=1;
ull s=0;
for(rg int i=1;i<len;++i) s=s*base+ch[i]-'0';
ch[0]='0';
for(rg int i=len;i<=l;++i){
s=s*base+ch[i]-'0'-pw[len]*(ch[i-len]-'0');
ans=1LL*ans*hash.query(len,s)%MOD;
}
return ans;
}
int main(){
std::ios::sync_with_stdio(0);
pw[0]=1;for(rg int i=1;i<=50;++i) pw[i]=pw[i-1]*base;
read(n),read(m);
for(rg int i=1;i<=n;++i) hash.add(1,read(a[i]),1);
while(m--){
int opt=read<int>();
if(opt==1){
int x=read<int>(),y=read<int>();
link(x,y);
}
else if(opt==2) cut(read<int>());
else{
scanf("%s",ch+1);
printf("%d\n",query(read<int>()));
}
}
return 0;
}
LOJ2303 「NOI2017」蚯蚓排队的更多相关文章
- 「NOI2017」蚯蚓排队 解题报告
「NOI2017」蚯蚓排队 这题真的草 你考虑\(k\)这么小,每次合并两个串,增加的有用串的数量是\(O(k^2)\)的,暴力加入这些串,求一下这些串的Hash值,塞到Hash表里面去 这里采用类似 ...
- LOJ#2303. 「NOI2017」蚯蚓排队
$n \leq 200000$的$1 \leq a_i \leq 6$的蚯蚓,有三种操作:让一只队头蚯蚓接在一只队尾蚯蚓后面:让一队蚯蚓从某个蚯蚓后面断成两队:问:给个字符串,问他的..算了你们直接看 ...
- LOJ 2303 「NOI2017」蚯蚓排队——链表+哈希表
题目:https://loj.ac/problem/2303 想到合并的时候可以只考虑接口附近的50个,但不太会分析复杂度,而且没有清楚地想到用哈希值对应个数. 看了题解才会…… 一直想用 splay ...
- LOJ_2305_「NOI2017」游戏 _2-sat
LOJ_2305_「NOI2017」游戏 _2-sat 题意: 给你一个长度为n的字符串S,其中第i个字符为a表示第i个地图只能用B,C两种赛车,为b表示第i个地图只能用A,C两种赛车,为c表示第i个 ...
- 【BZOJ4943】【NOI2017】蚯蚓排队(哈希)
[BZOJ4943][NOI2017]蚯蚓排队(哈希) 题面 BZOJ 洛谷 UOJ 题解 记得去年看网络同步赛的时候是一脸懵逼的. 昨天看到\(zsy\)做了,今天就看了看.. 这不是\(Hash\ ...
- 「NOI2017」游戏
「NOI2017」游戏 题目描述 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 \(A\).\(B\).\ ...
- loj #2305. 「NOI2017」游戏
#2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...
- LOJ2305 「NOI2017」游戏
「NOI2017」游戏 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行$n$场 ...
- LibreOJ2302 - 「NOI2017」整数
Portal Description 有一个整数\(x=0\),对其进行\(n(n\leq10^6)\)次操作: 给出\(a(|a|\leq10^9),b(b\leq30n)\),将\(x\)加上\( ...
随机推荐
- linux的文件夹权限
r:读取文件夹结构清单的权限,可以列出该文件夹下的所有文件. w:更改目录结构清单的能力,可以新建文件和目录,删除文件和目录(不管这个文件是否属于你),对文件和目录更名,移动文件和目录. x:具有x权 ...
- 自定义 ViewController 容器转场
本文转载至 http://blog.csdn.net/yongyinmg/article/details/40621463 在话题 #5 中,Chris Eidhof 向我们介绍了 iOS7 引入的新 ...
- Dbvisualizer 连接oracle数据库
软件及驱动下载: 链接:https://pan.baidu.com/s/1OhuRDCd6FDi21NyCEdN2dA 密码:0rtp 软件破解办法: 1. 找到<C:\Program File ...
- 【BZOJ3316】JC loves Mkk 分数规划+单调队列
[BZOJ3316]JC loves Mkk Description Input 第1行,包含三个整数.n,L,R.第2行n个数,代表a[1..n]. Output 仅1行,表示询问答案.如果答案是整 ...
- 配置过滤器filter对跨站脚本攻击XSS实现拦截
1.web.xml中配置filter [html] view plain copy <filter> <filter-name></filter-name> & ...
- Python中的TCP编程,实现客户端与服务器的聊天(socket)
参考大神blog:自己再写一个 https://blog.csdn.net/qq_31187881/article/details/79067644
- 九度OJ 1184:二叉树遍历 (二叉树)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3515 解决:1400 题目描述: 编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储). 例如如下的 ...
- 像使用linux一样使用mac
1 不能像使用windows一样使用mac 因为mac卸载不方便. 2 gcc的问题 就使用系统默认的gcc,即clang,要想使用原声的gcc是不行的,mac本身不支持.
- 求阶乘,输入一个正整数 n,输出n!
#include<stdio.h>int factorial (int n); int main(){ int n; scanf("%d",&n); print ...
- jquery 如何获取单选框的值
jquery 如何获取单选框的值 获取单选框的值有三种方式: 1.$('input:radio:checked').val():2.$("input[type='radio']:chec ...