蚯蚓排队题解
蚯蚓排队
题目描述
蚯蚓幼儿园有
所有蚯蚓用从
神刀手将会依次进行
-
给出
和 ,令 号蚯蚓与 号蚯蚓所在的两个队伍合并为一个队伍,具体来说,令 号蚯蚓紧挨在 号蚯蚓之后,其余蚯蚓保持队伍的前后关系不变。 -
给出
,令 号蚯蚓与紧挨其后的一只蚯蚓分离为两个队伍,具体来说,在分离之后, 号蚯蚓在其中一个队伍的队尾,原本紧挨其后的那一只蚯蚓在另一个队伍的队首,其余蚯蚓保持队伍的前后关系不变。 -
给出一个正整数
和一个长度至少为 的数字串 ,对于 的每个长度为 的连续子串 (这样的子串共有 个,其中 为 的长度),定义函数 ,询问所有这些的乘积对 取模后的结果。其中 的定义如下:
对于当前的蚯蚓队伍,定义某个蚯蚓的向后
输入格式
输入文件的第一行有两个正整数
第二行包含
接下来
-
( )表示:令 号与 号蚯蚓所在的两个队伍合并为一个队伍,新队伍中, 号蚯蚓紧挨在 号蚯蚓之后。保证在此操作之前, 号蚯蚓在某个队伍的队尾, 号蚯蚓在某个队伍的队首,且两只蚯蚓不在同一个队伍中。 -
( )表示:令 号蚯蚓与紧挨其后一个蚯蚓分离为两个队伍。保证在此操作之前, 号蚯蚓不是某个队伍的队尾。 -
( 为正整数, 为一个长度至少为 的数字串)表示:询问 的每个长度为 的子串 的 的乘积,对 取模的结果。 的定义见题目描述。
同一行输入的相邻两个元素之间,用恰好一个空格隔开。
输入文件可能较大,请不要使用过于缓慢的读入方式。
输出格式
输出到标准输出。
依次对于每个形如
数据范围与提示
保证
设
设
题解
自我感觉这题够恶心的,题面很长还难理解,大概是说给出
一眼就不很会,wzh先生直接投降看题解了,要用哈希表,然后我也去学哈希表,再来做题。
不得不说,这数据出的太绝了。直接想法:
对于操作
对于操作
然后就不知道怎么办了。
感谢wzh先生的提示
你看这个K它多可爱啊
你看这个c它多可爱啊
思考,思考......悟了!
当合并两个字符串时,由于保证
这样看来,最坏复杂的
而
总复杂度
Code
#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long
const int N=1e6;
const int mod=998244353;
const int M=1e7+19;
const int base=233;
const int K=50;
int n,m,a,b,k,l[N],t;
int h[N],p[N];
int cnt,head[N*50],nxt[N*50],num[N*50],sum[N*50],to[N],fo[N];
char s[N*10+14];
void insert(int key)
{
int hash=key%M;
for(int i=head[hash];i;i=nxt[i]){
if(num[i]==key){
sum[i]++;
return ;
}
}
cnt++;
sum[cnt]=1;
nxt[cnt]=head[hash];
head[hash]=cnt;
num[cnt]=key;
}
void cutoff(int key)
{
int hash=key%M;
for(int i=head[hash];i;i=nxt[i]){
if(num[i]==key){
sum[i]--;
return ;
}
}
}
int query(int key)
{
int hash=key%M;
for(int i=head[hash];i;i=nxt[i]){
if(num[i]==key){
return sum[i];
}
}
return 0;
}
inline int read()
{
int f=1,w=0;
char c=getchar();
while(c>'9'||c<'0'){
c=getchar();
}
while(c<='9'&&c>='0'){
w=w*10+(c-'0');
c=getchar();
}
return w*f;
}
void write1(int x){
if(x>9) write1(x/10);
putchar(x%10+48);
}
inline void write(int x){
write1(x);
}
signed main()
{
n=read();
m=read();
p[0]=1;
for(int i=1;i<=K;i++){
p[i]=(p[i-1]*base);
}
for(int i=1;i<=n;i++){
l[i]=read();
fo[i]=i;
to[i]=i;
insert((l[i]+'0'));
}
while(m--){
t=read();
if(t==1){
a=read();b=read();
int x=a,w=b,z,y;
int hx=0,hy=0;
for(int i=1;i<K;i++){
if(fo[x]==x)break;
x=fo[x];
}
for(int i=1;i<K;i++){
if(to[w]==w)break;
w=to[w];
}
z=a;
for(int i=1;;i++){
y=b;
hx=(l[z]+'0')*p[i-1]+hx;
hy=0;
for(int j=1;;j++){
hy=hy*base+(l[y]+'0');
insert(hx*p[j]+hy);
if(y==w||j+i>=K)break;
y=to[y];
}
if(z==x)break;
z=fo[z];
}
fo[b]=a;
to[a]=b;
}
else if(t==2){
a=read();
b=to[a];
int x=a,w=b,z,y;
int hx=0,hy=0;
for(int i=1;i<K;i++){
if(fo[x]==x)break;
x=fo[x];
}
for(int i=1;i<K;i++){
if(to[w]==w)break;
w=to[w];
}
z=a;
for(int i=1;;i++){
y=b;
hx=hx+(l[z]+'0')*p[i-1];
hy=0;
for(int j=1;;j++){
hy=hy*base+(l[y]+'0');
cutoff((hx*p[j])+hy);
if(y==w||j+i>=K)break;
y=to[y];
}
if(z==x)break;
z=fo[z];
}
fo[b]=b;
to[a]=a;
}
else{
scanf("%s",s);
k=read();
int shadow=0,ans=1,i;
bool flag=0;
for(i=0;i+1<k;i++){
shadow=(shadow*base+s[i]);
}
int len=strlen(s);
for(i=0;i+k-1<len;i++){
flag=1;
if(i==0){
shadow=(shadow*base+s[i+k-1]);
ans*=query(shadow);
ans%=mod;
}
else{
shadow=shadow*base-s[i-1]*p[k]+s[i+k-1];
ans*=query(shadow);
ans%=mod;
}
}
if(!flag)ans=0;
write(ans);puts(" ");
}
}
}
后续
题还是比较难想的,调了一下午后还是
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】