文章目录
R
e
s
u
l
t
Result
Result
H
y
p
e
r
l
i
n
k
Hyperlink
Hyperlink
D
e
s
c
r
i
p
t
i
o
n
Description
Description
S
o
l
u
t
i
o
n
Solution
Solution
C
o
d
e
Code
Code
R
e
s
u
l
t
Result
Result
H
y
p
e
r
l
i
n
k
Hyperlink
Hyperlink
https://ac.nowcoder.com/acm/contest/7607/C
D
e
s
c
r
i
p
t
i
o
n
Description
Description
有
n
n
n组询问,每次给出一个
t
t
t,再给定一个无限长的字符串,它的循环节是
s
s
s,试求这个串的一个最短前缀
s
‘
s^`
s‘,使得
t
t
t是
s
‘
s^`
s‘的一个子序列。其中
t
t
t的某些位置可能是一个星号,表示这个位置可以是任意字符。
数据范围:
∣
s
∣
≤
1
0
4
,
t
的真正长度
≤
1
0
1
0
5
|s|\leq 10^4,t\text{的真正长度}\leq 10^{10^5}
∣s∣≤104,t的真正长度≤10105
S
o
l
u
t
i
o
n
Solution
Solution
设
t
o
t
i
tot_i
toti表示原串中某个字符的个数,
q
z
i
,
j
qz_{i,j}
qzi,j表示
s
s
s的前
i
i
i位,
j
j
j字符的出现次数
a
p
p
e
a
r
i
,
j
appear_{i,j}
appeari,j表示
s
s
s串中
i
i
i字符第
j
j
j次出现的位置
考虑计算循环了几个
s
s
s——
x
h
xh
xh 考虑循环后需要某个字符多少个——
n
e
e
d
need
need(当
s
t
i
≠
st_i\neq
sti=星号时,这个字符就是
s
t
i
st_i
sti,否则这个字符可以是任意字符) 考虑上次循环的结束位置——
l
a
s
t
last
last 对于输入的数很大的话,要用类似于高精度的方法对其进行处理
最后统计答案即可 时间复杂度:
O
(
26
∣
s
∣
+
n
∣
t
∣
)
O(26|s|+n|t|)
O(26∣s∣+n∣t∣)
C
o
d
e
Code
Code
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define mod 998244353
using namespace std
;char s
[10010],st
[100010],ybd
;
int len
,n
,appear
[26+150][10010];
LL xh
,need
,tot
[26+150],qz
[10010][26+150],once
,ans
,last
;
inline LL
read()
{
char c
;LL d
=1,f
=0;
while(c
=getchar(),!isdigit(c
)) if(c
=='-') d
=-1;f
=(f
<<3)+(f
<<1)+c
-48;
while(c
=getchar(),isdigit(c
)) f
=(f
<<3)+(f
<<1)+c
-48;
return d
*f
;
}
inline LL
ksm(LL x
,LL y
)
{
LL res
=1;
for(;y
;y
>>=1,(x
*=x
)%=mod
)
if(y
&1) (res
*=x
)%=mod
;
return res
;
}
inline bool tp()
{
for(register int i
=1;i
<=strlen(st
+1);i
++) if(st
[i
]!='*'&&!isdigit(st
[i
])&&tot
[st
[i
]]==0) return true;
return false;
}
signed main()
{
scanf("%s",s
+1);len
=strlen(s
+1);s
[len
+1]=s
[1];
for(register int i
=1;i
<=len
;i
++)
{
tot
[s
[i
]]++;
memcpy(qz
[i
],qz
[i
-1],sizeof(qz
[i
-1]));
appear
[s
[i
]][++appear
[s
[i
]][0]]=i
;
qz
[i
][s
[i
]]++;
}
n
=read();
while(n
--)
{
scanf("%s",st
+1);
if(tp()) {puts("-1");continue;}
ans
=0;last
=1;
for(register int i
=1;i
<=strlen(st
+1);i
++)
{
ybd
=st
[i
];
once
=st
[i
]=='*'?len
:tot
[st
[i
]];
xh
=0;need
=0;
if(isdigit(st
[i
+1]))
{
while(isdigit(st
[i
+1]))
{
xh
=((xh
<<3)+(xh
<<1))%mod
;
need
=((need
<<3)+(need
<<1)+st
[++i
]-48)%mod
;
(xh
+=need
/once
)%=mod
;need
%=once
;
}
}
else need
=1;
if(ybd
=='*') need
+=once
-(len
-last
+1);
else need
+=once
-(tot
[ybd
]-qz
[last
-1][ybd
]);
if(need
>once
) need
-=once
,xh
++;
if(xh
==0) xh
=mod
;
if(need
==0) need
+=once
,xh
--;
if(ybd
!='*')
{
ans
+=appear
[ybd
][need
]-last
+1;
last
=appear
[ybd
][need
]%len
+1;
}
else
{
ans
+=need
-last
+1;
last
=need
%len
+1;
}
(ans
+=len
*xh
%mod
)%=mod
;
}
printf("%lld\n",ans
);
}
}