[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*)”的匹配函数

python小技巧

请解释 Shape r = new Square() 的结果以及为啥 Square 的方法不可用

C刷题记录-1015

hdu 1518 Square

spring-cloud-square源码速读(spring-cloud-square-okhttp篇)