首页 > 其他分享 >Luogu P10674 【MX-S1-T3】电动力学

Luogu P10674 【MX-S1-T3】电动力学

时间:2024-07-03 09:52:31浏览次数:14  
标签:int Luogu S1 T3 方点 maxn low operatorname mod

首先考虑这个 \(S, T\) 肯定需要固定一个算另一个的方案数。
如果固定 \(S\),会发现非常不好给 \(T\) 下限制。
于是考虑固定 \(T\),对 \(S\) 计数。

首先考虑如果 \(T\) 只有 \(2\) 个点 \(x, y\),该怎么对 \(S\) 计数。
考虑到这个简单路径的定义是不经过重点,考虑找到点双。
然后能发现,只要是在 \(x\to y\) 这个路径上经过的点双里的点,都是可以放入 \(S\) 的。

于是这启发找到点双后建出圆方树并在上面 DP

首先要考虑圆点方点的权值 \(a_u\)。
根据前面说到的,可以知道经过的方点的对应的点集的并就是可以放入 \(S\) 的点集。

令 \(\operatorname{siz}_u\) 为方点 \(u\) 对应的点的个数,令 \(U\) 为经过的方点的集合。
考虑到对于由圆点连接的两个方点都会算上这个原点,应该 \(-1\)。
所以能够知道 \(|S| = (\sum\limits_{u\in U} \operatorname{siz}_u) - (|U| - 1) = (\sum\limits_{u\in U}(\operatorname{siz}_u - 1)) + 1\)。
那么这样就只与 \(u\) 有关而不用考虑 \(|U|\) 之类的东西了。
于是可以把方点的权值设为 \(a_u = \operatorname{siz}_u - 1\), 圆点设置为 \(a_u = 0\)。
对于少考虑的 \(1\) 最后补上就行了。

同时需要考虑到知道了 \(T\),那么哪些方点 \(u\) 是能被经过的。
这个易知只要 \(u\) 在 \(T\) 对应在圆方树上的虚树中,\(u\) 就可以经过。

同时如果知道了 \(T\) 对应的 \(S\),其对应的权值显然为 \(2^{|S|}\)。

于是就可以考虑 DP 了。
先定义 \(\operatorname{subtree}_u\) 表示 \(u\) 的子树,\(\operatorname{son}_u\) 为 \(u\) 的儿子,\(\operatorname{val}(u \to v)\) 表示 \(u\to v\) 这条路径上经过的点 \(w(w\not = v)\) 的 \(\prod 2^{a_w}\),也就是这条路径上的方点产生的贡献。

考虑从上面说到的虚树来考虑,令 \(f_u\) 为 \(u\) 为虚树的根是对应的方案数。
但会发现这样根本不好转移,因为虚树的根可能是因为两个不同子树里的根在此处合并导致的。
于是考虑在令 \(g_u\) 为 \(u\) 子树内任意一个点为根对应的方案数,具体表示一下就是 \(g_u = \sum\limits_{v\in \operatorname{subtree}(u)} f_v\times \operatorname{val}(u\to v)\)。

然后考虑转移,分为圆点和方点:

  1. 对于圆点为根,有 \(2\) 种选择:自己本身就被选中或者有两个不同子树有点被选中。
    所以说如果有 \(\ge 2\) 个不同子树内有被选中的,\(2\) 种方法都可以;但若是只有 \(1\) 个子树或者没有,就只可能是自己被选中 \(1\) 种。
    可以对 \(g_v(v\in \operatorname{son}_u)\) 做个背包得到 \(h_{0\sim 2}\),其中 \(h_x(0\le x\le 1)\) 分别代表有 \(x\) 个不同子树内有点被选中的方案数,\(h_2\) 代表有 \(\ge 2\) 个不同子树内有点被选中的方案数。
    那么有 \(f_u = 2h_2 + h_1 + h_0\)。
  2. 对于方点为根,那么就只能是有两个不同子树有点被选中了。
    同上一样对 \(g_v(v\in \operatorname{son}_u)\) 做背包得到 \(h_{0\sim 2}\)。
    那么因为 \(u\) 是方点,有对应的贡献 \(2^{a_u}\),所以有 \(f_u = h_2\times 2^{a_u}\)。

然后对于 \(g_u\),考虑有 \(\operatorname{val}(u\to w) = 2^{a_u}\operatorname{val}(v\to w)(w\in \operatorname{subtree}(v), v\in \operatorname{son}_u)\),于是只需所有 \(g_v\) 乘上 \(2^{a_u}\) 后,再加上新出现的 \(f_u\) 就行了。
即 \(g_u = h_1 2^{a_u} + f_u\)。

最后记得补上之前少的 \(1\),乘 \(2\) 即可,并补上 \(S = T = \varnothing\) 的 \(1\)。

时间复杂度 \(\mathcal{O}(n)\)。

#include<bits/stdc++.h>
using ll = long long;
constexpr ll mod = 998244353;
const int maxn = 1e6 + 10;
int n, N;
ll pw[maxn];
std::vector<int> G[maxn], to[maxn];
int low[maxn], dfn[maxn], dt, stk[maxn], top;
int siz[maxn];
void dfs1(int u) {
   low[u] = dfn[u] = ++dt, stk[++top] = u;
   for (int v : G[u]) {
      if (dfn[v]) low[u] = std::min(low[u], dfn[v]);
      else {
         dfs1(v), low[u] = std::min(low[u], low[v]);
         if (dfn[u] == low[v]) {
            N++, to[u].push_back(n + N), to[n + N].push_back(u);
            int t;
            do {t = stk[top--]; to[t].push_back(n + N), to[n + N].push_back(t);} while (t != v);
            siz[n + N] = to[n + N].size();
         }
      }
   }
}
ll f[maxn], g[maxn];
void dfs2(int u, int fa) {
   if (u != 1 && to[u].size() == 1)
      return f[u] = g[u] = 1, void();
   ll h[3] = {1, 0, 0};
   for (int v : to[u]) {
      if (v == fa) continue;
      dfs2(v, u);
      h[2] = (h[2] * (g[v] + 1) + h[1] * g[v]) % mod, h[1] = (h[1] + h[0] * g[v]) % mod;
   }
   if (u > n) f[u] = pw[siz[u] - 1] * h[2] % mod, g[u] = (pw[siz[u] - 1] * h[1] + f[u]) % mod;
   else f[u] = (2ll * h[2] + h[1] + h[0]) % mod, g[u] = (h[1] + f[u]) % mod;
}
int main() {
   int m; scanf("%d%d", &n, &m);
   for (int i = pw[0] = 1; i <= n; i++) (pw[i] = pw[i - 1] << 1) >= mod && (pw[i] -= mod);
   for (int x, y; m--; )
      scanf("%d%d", &x, &y), G[x].push_back(y), G[y].push_back(x);
   dfs1(1);
   dfs2(1, 0);
   ll ans = 0;
   for (int i = 1; i <= n + N; i++) (ans += f[i]) %= mod;
   printf("%lld\n", (2ll * ans + 1ll) % mod);
   return 0;
}

标签:int,Luogu,S1,T3,方点,maxn,low,operatorname,mod
From: https://www.cnblogs.com/rizynvu/p/18281036

相关文章

  • windows10添加多个东芝14T硬盘系统加载不出来的问题
    windows10添加多个东芝14T硬盘系统加载不出来的问题1.明明是加了一个14T东芝硬盘,系统就是加载不出来,从BIOS上也能看2.解决方法此电脑右键–》管理3.设置管理器—》标准sataahci控制器4.右键卸载设备,点击卸载,系统系统重启5.重启好后就能看到新挂的硬盘了......
  • Nuxt3 的生命周期和钩子函数(八)
    title:Nuxt3的生命周期和钩子函数(八)date:2024/6/30updated:2024/6/30author:cmdragonexcerpt:摘要:本文介绍了Nuxt3框架中的一些重要生命周期钩子,如prepare:types用于自定义TypeScript配置和类型声明,listen用于在开发服务器启动时注册自定义事件监听器,schema:ex......
  • Nuxt3 的生命周期和钩子函数(七)
    title:Nuxt3的生命周期和钩子函数(七)date:2024/6/30updated:2024/6/30author:cmdragonexcerpt:摘要:文章阐述了Nuxt3中Nitro生命周期钩子的使用,如nitro:config自定义配置、nitro:init注册构建钩子、nitro:build:before/after调整构建设置及处理公共资产、prerend......
  • windows10用conda搭建tensorflow的gpu环境
    在tensorflow官方网址上也列举了很多方法,但都很麻烦,包括docker也没有办法在win10下应用gpu来计算。记录我的检查过程。在官网搜集有用的资料。“在Windows环境中从源代码构建”中提到了经过测试后,可用的配套版本,找到一个最新的是:|版本|Python版......
  • SpringBoot3连接Mysql数据库
    pom引入包,启动器<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.o......
  • ADS1256芯片说明
    本篇文章先总结一下24位的8通道24bit高精度采集的24位ADS1256,本篇文章不是纯粹的datasheet的抄袭,而是datasheet的总结,高度概括,以及对我们编程有用的思路,我大概看了一下网上流传的版本,大多数都是STM32,另外有一份是verilog不知道是谁写的,各个网都有,它是多通道采集,仅仅使用了一种模式......
  • springboot3(cloud 2022.0.0)整合seata1.7.1
    一、第一步下载对应版本的seata服务  二、修改conf下的application.yml配置注意:主要是连接nacos的一些配置:注册中心和服务发现的配置1#Copyright1999-2019Seata.ioGroup.2#3#LicensedundertheApacheLicense,Version2.0(the"License");4#you......
  • Luogu P9542 [湖北省选模拟 2023] 棋圣 alphago
    2023.08.19:修改了一处笔误。手玩发现对于一颗生成树,如果存在至少一个点的度数\(>2\)(即不为链),那么肯定能使得所有棋子都在一条边的两个端点上。因为有度数\(>2\)的点的存在,这里就可以合并与其相连的点的棋子。先考虑非链的情况的答案,记两部分棋子黑白棋子颜色分别为\(c(a/......
  • Luogu P6864 [RC-03] 记忆
    先考虑没有\(3\)操作该怎么做。对于当前字符串把其分成多组互不包含的括号的形式,即\((\cdots)()()\)这样,考虑经过\(1/2\)操作后对互不包含的括号组数\(b\)和答案\(v\)会产生什么影响。\(1\)操作,加上过后便会多上一组互不包含的括号,\(b\leftarrowb'+1\),同时这个......
  • SprongBoot3整合Knife4j
    大家好,我是晓凡。写在前面在上一篇文章,我们详细介绍了SpringBoot3怎么整合SpringDoc实现在线接口文档。但是,有不少小伙伴都觉得接口界面太丑了。有没有什么更美观一点的UI界面呢?当然是有的了,毕竟这是一个看脸的时代,Knife4j这不来了么。一、界面比较这儿我们将上一篇文章......