当前位置 : 主页 > 编程语言 > 其它开发 >

一个小 Trick

来源:互联网 收集:自由互联 发布时间:2022-05-30
trick 平方变两次 一个状态 \(S\) 有一个贡献,所有状态 \(S\) 组成集合 \(U\) . 然后我们要统计下面这个东西 \[ans=\sum_{S\in U}f^2(S)\] 然后我们就可以看作是选两个 \(U\) 里的 \(S_1, S_2\) ,然后
trick

平方变两次

一个状态 \(S\) 有一个贡献,所有状态 \(S\) 组成集合 \(U\) .

然后我们要统计下面这个东西

\[ans=\sum_{S\in U}f^2(S) \]

然后我们就可以看作是选两个 \(U\) 里的 \(S_1, S_2\),然后 \(S_1=S_2\) 的方案数 .

这样就把一个带平方的贡献问题转化成一个简单的选择了 .

让我们看一个实例:

NOI2009 管道取珠

两个字符串 \(S,T\) .

整一个仅含 \(1, 2\) 的序列 \(\{a\}\),用以下步骤生成一个字符串 \(U\)

  • 扫描序列 \(\{a\}\) .
  • 目前扫到了 \(x\)
    • 如果 \(x\)\(1\),从 \(S\) 的末尾拿一个字符放到 \(U\) 的开头,然后把 \(S\) 末尾那个字符删了 .
    • 如果 \(x\)\(2\),从 \(T\) 的末尾拿一个字符放到 \(U\) 的开头,然后把 \(T\) 末尾那个字符删了 .

然后最后 \(S,T\) 都删没了得到的 \(U\) 就是生成出来的字符串 .

所有只有 \(n\)\(1\)\(m\)\(2\) 的序列是合法的 .

\(f(X)\) 为序列 \(X\) 能被多少给合法序列生成 .

\[\sum_X f^2(X) \]

\(1024523\) 取模 .

\(1\le n,m\le 500\) .

题解:

平方变两次,于是变成生成两次生成了相同的串的方案数 .

直接大力普及组 DP,令 \(dp_{i,j,k,l}\) 表示第一次 \(S\)\(i\) 个,\(T\)\(j\) 个;第一次 \(S\)\(k\) 个,\(T\)\(l\) 个的答案 .

然后轻松转移把 .

显然 \(i+j=k+l\),于是可以滚掉一维度 .

于是这道题就被 \(O(n^2m)\) 解决了 .

一些类似的题目:

  • BJOI2017 机动训练
  • UOJ #667 提问系统(需要把原 Trick 推广到单项式)
  • AGC013E Placing Squares

以下是博客签名,正文无关

网友评论