[ABC299F] Square Subsequence
Posted 灰鲭鲨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ABC299F] Square Subsequence相关的知识,希望对你有一定的参考价值。
Problem Statement
You are given a string $S$ consisting of lowercase English letters. Print the number of non-empty strings $T$ that satisfy the following condition, modulo $998244353$.
The concatenation $TT$ of two copies of $T$ is a subsequence of $S$ (not necessarily contiguous).
Constraints
- $S$ is a string consisting of lowercase English letters whose length is between $1$ and $100$, inclusive.
Input
The input is given from Standard Input in the following format:
$S$
Output
Print the answer.
Sample Input 1
ababbaba
Sample Output 1
8
The eight strings satisfying the condition are a
, aa
, ab
, aba
, b
, ba
, bab
, and bb
.
Sample Input 2
zzz
Sample Output 2
1
The only string satisfying the condition is z
.
Note that this string contributes to the answer just once, although there are three ways to extract the subsequence zz
from $S = S_1S_2S_3 = $ zzz
: $S_1S_2 = $ zz
, $S_1S_3 = $ zz
, and $S_2S_3 = $ zz
.
Sample Input 3
ppppqqppqqqpqpqppqpqqqqpppqppq
Sample Output 3
580
考虑枚举两个串的开头,就设为 \\(a\\) 和 \\(b\\),满足 \\(s_a=s_b\\),然后分别跳子序列自动机。
为了使所有跳的操作不重复,我们应该强制第一个串的开头就是某个字母的第一次出现。
然后进行dp,定义 \\(dp_i,j\\) 为第一个串目前跳的到了点 \\(i\\),第二个串跳到了点 \\(j\\) 的情况。当然,要满足 \\(i<a\\)
理论上,要把所有的 \\(dp_i,j\\) 全部计入答案。但是我们发现如果这样会算重。比如串 ababab
,那么枚举第一个 a
时,会把 ab
这个串数两次。去一下重就可以了。如果 \\(i\\) 的下一个 \\(s_a\\) 的出现地方时 \\(b\\),那么我们才计入答案。
复杂度:枚举两个串开头是 \\(O(n)\\) 的,dp \\(O(|\\Sigma|n^2)\\),总复杂度 \\(O(n^3|\\Sigma|)\\)
#include<bits/stdc++.h>
using namespace std;
const int N=105,P=998244353;
int n,nx[N][26],dp[N][N],ans;
char s[N];
void add(int&x,int y)
x=x+y>=P? x+y-P:x+y;
int main()
scanf("%s",s+1),n=strlen(s+1);
for(int i=n-1;i>=1;i--)
memcpy(nx[i],nx[i+1],sizeof(nx[i]));
nx[i][s[i+1]-\'a\']=i+1;
// printf("%d\\n",nx[1][0]);
for(int i=0;i<26;i++)
int st=0;
for(int j=1;j<=n;j++)
if(s[j]-\'a\'^i)
continue;
if(!st)
st=j;
else
// printf("hjh:%d %d\\n",st,j);
memset(dp,0,sizeof(dp));
dp[st][j]=1;
for(int a=st;a<j;a++)
for(int b=j;b<=n;b++)
// if(dp[a][b])
// printf("%d %d\\n",a,b);
if(nx[a][i]==j)
add(ans,dp[a][b]);
for(int c=0;c<26;c++)
if(nx[a][c]<j&&nx[a][c]&&nx[b][c])
add(dp[nx[a][c]][nx[b][c]],dp[a][b]);
// add(ans,(bool)st);
printf("%d",ans);
请解释 Shape r = new Square() 的结果以及为啥 Square 的方法不可用
【中文标题】请解释 Shape r = new Square() 的结果以及为啥 Square 的方法不可用【英文标题】:Please explain the outcome of Shape r = new Square() and why Square's methods aren't available请解释 Shape r = new Square() 的结果以及为什么 Square 的方法不可用 【发布时间】:2021-10-20 09:42:29 【问题描述】:我正在研究 Jeff Fritz 的 c# tutorial videos,并且有一些类似这样的代码使用抽象类:
public abstract class Shape
public class Rectangle : Shape
public class Square : Rectangle
public string SquareOnlyMethod() return "I am a square";
public static void Main()
Square s = new Square();
Console.WriteLine(s.GetType()); // Square
Console.WriteLine(s is Shape); // True
Console.WriteLine(s is Rectangle); // True
Console.WriteLine(s is Square); // True
Console.WriteLine(s.SquareOnlyMethod()); // I am a square
Shape r = new Square();
Console.WriteLine(r.GetType()); // Square
Console.WriteLine(r is Shape); // True
Console.WriteLine(r is Rectangle); // True
Console.WriteLine(r is Square); // True
Console.WriteLine(r.SquareOnlyMethod()); // 'Shape' does not contain a definition for 'SquareOnlyMethod' and no extension method 'SquareOnlyMethod' accepting a first argument of type 'Shape' could be found
有人可以解释一下吗?
-
当我们执行
Shape r = new Square();
时实际创建了什么?是Shape
还是Square
?
为什么GetType
返回Square
却找不到Square
类中的方法?
Jeff 说(如果我理解正确的话)“‘Shape` 是用 Square 的足迹创建的”,然后继续前进。
Fiddle
【问题讨论】:
"它是形状还是正方形?"两者都是,因为所有 Square 对象也是 Shape 对象。 您创建使用new
关键字初始化的内容,在本例中为 Square
实例。但是您将它分配给它的基本类型Shape
的变量。通过这种方式,您隐藏了它是Square
的事实。你总是可以将它转换回Square
,然后你也可以使用SquareOnlyMethod
。因此,即使它仍然是 Square
,编译器也不允许使用在 Square
中定义的方法,如果它被声明为 Shape
,因为不是每个 Shape
都有这个方法。
【参考方案1】:
您看到的问题始于以下行 Shape r = new Square();
,因为即使您正在创建 Square 但使用基本类型。我假设 Jeff 试图向您展示的概念是 多态性,可以在此处查看形状问题的更好示例https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/object-oriented/polymorphism。
在 Microsoft 示例中,您可以看到基类为任何派生类(形状)提供了通用功能,以利用、扩展或覆盖。因此,您可以潜在地将不同 Shape 子代的单个数组视为 Shapes,并跨任何子 shape(因此有多种形式)访问或调用方法(虚拟覆盖)。
var shapes = new List<Shape>
new Rectangle(),
new Triangle(),
new Circle()
;
// Polymorphism at work #2: the virtual method Draw is
// invoked on each of the derived classes, not the base class.
foreach (var shape in shapes)
shape.Draw();
【讨论】:
谢谢。这是实例化期间“装箱”的一个例子吗?创建了一个 Square 但只展示基类 Shape 的方法?让我困惑的是 GetType 位。 不,当您需要使用值类型代替引用类型时会发生装箱,例如object integer = 1
。在这里,所有类型都是引用类型,因此不会发生装箱。
@EvilDr GetType 返回运行时类型,因为运行时的实例类型是 Square - 这就是您将看到的。查看 docs.microsoft.com/en-us/dotnet/api/… 和 docs.microsoft.com/en-us/dotnet/api/… 这些是了解差异的好参考。以上是关于[ABC299F] Square Subsequence的主要内容,如果未能解决你的问题,请参考以下文章
错误:没有调用“Square::Square(Square Color &,Location*)”的匹配函数