【九省联考2018】秘密袭击【树形dp】【生成函数】【线段树合并】【多项式插值】

题意:nnn 个点的带点权的树,点权最大值为 www,求所有连通子图第 kkk 大权值之和模 641236412364123

n,w≤1666n,w\leq 1666n,w1666,时限 5s。

idea 很好的题,可惜被暴力艹过去了。

首先如果点权只有 000111,我们相当于求包含至少 kkk111 的连通子图个数。可以设 f(u,k)f(u,k)f(u,k) 表示 uuu 为根的可空连通子图中有恰好 kkk111 的数量,然后就是刻在 DNA 里的转移方程

f(u,k)⟵∑i=0kf(u,i)g(v,k−i)f(u,k)\longleftarrow\sum_{i=0}^kf(u,i)g(v,k-i)f(u,k)i=0kf(u,i)g(v,ki)

f(u,0)⟵f(u,0)+1f(u,0)\longleftarrow f(u,0)+1f(u,0)f(u,0)+1

边界: f(u,valu)=1f(u,val_u)=1f(u,valu)=1

我们枚举值域,大于等于的设为 111,小于的设为 000,算出方案数乘上差值,就可以 O(n2w)\Omicron(n^2w)O(n2w) 踩标算了。

注意到这个转移方程是卷积的形式,所以可以写成生成函数

fu(x)=∏v∈son(u)fv(x)+1f_u(x)=\prod_{v\in son(u)}f_v(x)+1fu(x)=vson(u)fv(x)+1

然后你要求所有点的和,所以开个 ggg 顺便记一下

gu(x)=∑v∈son(u)gv(x)+fu(x)−1g_u(x)=\sum_{v\in son(u)}g_v(x)+f_u(x)-1gu(x)=vson(u)gv(x)+fu(x)1

所有的生成函数都是 nnn 次的,所以考虑带 n+1n+1n+1 个点值进去算。因为不是 NTT 模数,所以只能带一般的点值最后再插值回来。

这样还是 O(n2w)\Omicron(n^2w)O(n2w) 的。带点值这步不好优化,但后面的枚举值域看起来可以优化一下。

可以动态 dp,但常数巨大,还没暴力跑得快。

注意到不同的阀值的计算过程是一样的,可以考虑用线段树合并维护所有阀值的答案。

开个长度为值域的线段树,我们在线段树的每个叶子记录这个阀值的 (f,g)(f,g)(f,g),初值为 (0,0)(0,0)(0,0)。你需要维护以下操作:

  1. 开头的 fff 区间加和区间乘。
  2. 合并两棵线段树,fff 对应位置相乘, ggg 对应位置相加。
  3. 最后的 f←f+1,g←g+ff\leftarrow f+1,g\leftarrow g+fff+1,gg+f

手玩一个标记 (a,b,c,d)(a,b,c,d)(a,b,c,d) 表示 (f,g)⟵(af+b,cf+g+d)(f,g)\longleftarrow (af+b,cf+g+d)(f,g)(af+b,cf+g+d),就可以做了。

关于有懒标记的线段树合并:线段树合并的过程中两边有一边没有儿子时直接返回,这样 pushdown 次数和递归次数同阶,不影响复杂度。

最后插值即可。

复杂度 O(wnlog⁡w)\Omicron(wn\log w )O(wnlogw)

#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <vector>
#include <algorithm>
#define MAXN 2005
using namespace std;
inline int read()
{int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans;
}
const int MOD=64123;
typedef long long ll;
inline int add(const int& x,const int& y){return x+y>=MOD? x+y-MOD:x+y;}
inline int dec(const int& x,const int& y){return x<y? x-y+MOD:x-y;}
vector<int> e[MAXN];
inline int qpow(int a,int p)
{int ans=1;while (p){if (p&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD,p>>=1;}return ans;
}
struct data
{int a,b,c,d;inline data(const int& a=1,const int& b=0,const int& c=0,const int& d=0):a(a),b(b),c(c),d(d){}
};
inline data operator *(const data& x,const data& y){return data((ll)x.a*y.a%MOD,((ll)y.a*x.b+y.b)%MOD,((ll)x.a*y.c+x.c)%MOD,((ll)x.b*y.c+x.d+y.d)%MOD);}
int n,k,w,val[MAXN];
int ch[MAXN<<5][2],cnt;
data tag[MAXN<<5];
inline void clear()
{for (int i=1;i<=cnt;i++) ch[i][0]=ch[i][1]=0,tag[i]=data();cnt=0;
}
inline void pushtag(int x,const data& v){tag[x]=tag[x]*v;}
inline void pushdown(int x)
{if (!ch[x][0]) ch[x][0]=++cnt;if (!ch[x][1]) ch[x][1]=++cnt;pushtag(ch[x][0],tag[x]),pushtag(ch[x][1],tag[x]);tag[x]=data();
}
int merge(int x,int y)
{if (!x||!y) return x|y;if (!ch[x][0]&&!ch[x][1]) swap(x,y);if (!ch[y][0]&&!ch[y][1]){tag[x]=tag[x]*data(tag[y].b,0,0,0);tag[x]=tag[x]*data(1,0,0,tag[y].d);return x;}pushdown(x),pushdown(y);ch[x][0]=merge(ch[x][0],ch[y][0]);ch[x][1]=merge(ch[x][1],ch[y][1]);return x;
}
void modify(int& x,int l,int r,int ql,int qr,data v)
{if (!x) x=++cnt;if (ql<=l&&r<=qr) return pushtag(x,v);if (qr<l||r<ql) return;int mid=(l+r)>>1;pushdown(x);modify(ch[x][0],l,mid,ql,qr,v),modify(ch[x][1],mid+1,r,ql,qr,v);
}
int querysum(int x,int l,int r)
{if (l==r) return tag[x].d;int mid=(l+r)>>1;pushdown(x);return add(querysum(ch[x][0],l,mid),querysum(ch[x][1],mid+1,r));
}
int rt[MAXN];
void dfs(int u,int f,int v)
{modify(rt[u],1,w,1,w,data(0,1,0,0));modify(rt[u],1,w,1,val[u],data(v,0,0,0));for (int i=0;i<(int)e[u].size();i++)if (e[u][i]!=f){dfs(e[u][i],u,v);rt[u]=merge(rt[u],rt[e[u][i]]);}modify(rt[u],1,w,1,w,data(1,1,1,0));
}
int calc(int v)
{clear();for (int i=1;i<=n;i++) rt[i]=0;dfs(1,0,v);return querysum(rt[1],1,w);
}
int ans[MAXN],s[MAXN],tmp[MAXN],f[MAXN];
int main()
{n=read(),k=read(),w=read();for (int i=1;i<=n;i++) val[i]=read();for (int i=1;i<n;i++){int u,v;u=read(),v=read();e[u].push_back(v),e[v].push_back(u);}for (int v=1;v<=n+1;v++)ans[v]=calc(v);s[0]=1;for (int i=1;i<=n+1;i++){for (int j=i;j>=1;j--)s[j]=dec(s[j-1],(ll)i*s[j]%MOD);		s[0]=(ll)s[0]*(MOD-i)%MOD;}for (int i=1;i<=n+1;i++){int x=ans[i];for (int j=1;j<=n+1;j++) if (i!=j) x=(ll)x*qpow(dec(i,j),MOD-2)%MOD;tmp[0]=(ll)s[0]*qpow(MOD-i,MOD-2)%MOD;for (int j=1;j<=n+1;j++) tmp[j]=(ll)dec(tmp[j-1],s[j])*qpow(i,MOD-2)%MOD;for (int j=0;j<=n+1;j++) f[j]=(f[j]+(ll)x*tmp[j])%MOD;}int res=0;for (int i=k;i<=n;i++) res=add(res,f[i]);cout<<res;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314769.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员修神之路--做好分库分表其实很难之二

菜菜哥&#xff0c;上次听你给我讲了分库的情况后&#xff0c;我明白了很多&#xff0c;能再给我讲讲分表吗有收获就好&#xff0c;分表其实有很多情况和分库类似还有不一样的情况吗&#xff1f;有呀&#xff0c;本来数据库和表是不同层面的东西&#xff0c;肯定有差异那你给讲…

2021牛客暑期多校训练营3 B Black and white 最小生成树 + 思维

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 对于每个数的位置(i,j)(i,j)(i,j)&#xff0c;如果将这个位置染黑&#xff0c;那么我们连一个i−>jni->jni−>jn的边&#xff0c;可以发现我们的操作不影响连通性。如果想要全部染…

关于WinForms的跨显示器DPI自适应

点击上方蓝字关注“汪宇杰博客”导语WinForms 是运行在Windows上的传统.NET桌面应用技术框架。由于历史原因&#xff0c;它对高DPI以及跨不同DPI屏幕的支持有些问题&#xff0c;本文将探索尽可能的解决方案。Windows 的“黑历史”Windows 系统的默认DPI&#xff08;更确切的说法…

【THUSC2018】史莱姆之友【长链剖分】【链分治NTT】

不知道这题能不能发出来&#xff0c;如果不能请联系我&#xff0c;我什么都会做的 题意&#xff1a;给一棵 nnn 个结点的树&#xff0c;每个结点有个 axbaxbaxb&#xff0c;求所有根到叶子的乘积之和。系数模 998244353998244353998244353。 链的情况就是分治 NTT&#xff0c…

HDU - 6964 I love counting 树状数组套01tire

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个长度为nnn的数组&#xff0c;每次询问l,r,a,bl,r,a,bl,r,a,b代表询问[l,r][l,r][l,r]区间内有多少个不同的数x⊕a≤bx\oplus a\le bx⊕a≤b。 n≤1e5,a,b,x≤n1n\le1e5,a,b,x\le n1n≤1e5,a,b,x≤n1…

.NET开发框架(九)-NLB网络负载平衡配置实战(视频)

&#xff08;NLB配置实战教程-有声视频-第二节&#xff09;请持续关注公众号&#xff0c;第三节&#xff08;NLBARR)正在录制中~第六章IIS负载均衡教程&#xff0c;至今共有37人参与学习尚未学习第六章-IIS负载均衡-视频教程的童靴&#xff0c;赶紧跟上进度&#xff0c;别掉队了…

WC 赛前总结

不要试图得到不属于自己的东西&#xff0c;这样反而容易丢掉本该拿到的分。完全放弃某一道题时一定要慎重&#xff0c;也不要把希望寄托于肝出某一道题。题多读几遍&#xff0c;手算样例&#xff0c;并充分理解了样例解释之后再开始想。读错题浪费时间都是小事&#xff0c;如果…

HDU - 6959 zoto 莫队 + 值域分块

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你nnn个数&#xff0c;每个数有个值&#xff0c;有mmm次询问&#xff0c;每次给定l,r,y1,y2l,r,y1,y2l,r,y1,y2代表查询[l,r][l,r][l,r]区间内在[y1,y2][y1,y2][y1,y2]值域内有多少数出现了。 n≤1e5,m≤1…

C#各版本新增加功能

本系列文章主要整理并介绍 C# 各版本的新增功能。C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发布&#xff0c;但是当前处于预览状态。预计在2019年9月正式发布。目前提供以下功能可供试用&#xff1a;Readonly 成员默认接口成员【*重要&#xff0c;…

很抱歉,博主 AFO 了

遭受了非常严重的考场 debuff&#xff0c;彻底滚粗。 明明全打暴力都还有希望&#xff0c;非要花一半时间去做看起来很简单的 T3&#xff1b;明明接着全打暴力也有希望&#xff0c;非要去写 T2 明显写不出来的线段树合并&#xff1b;明明 T1 还可以骗点分&#xff0c;非要连个…

宣告推出.NET Core 3.0 Preview 7

译&#xff1a;艾心0626今天&#xff0c;我们宣布推出.NET Core 3.0 Preview 7。我们已经从创建新特性阶段过渡到了完善版本阶段。对于接下来的预览版&#xff0c;我们将把重点放在质量(改进)上。在Windows&#xff0c;macOS和Linux上下载.NET Core 3.0 Preview 7。.NET Core 3…

hdu 1028 Ignatius and the Princess III 母函数入门

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个数nnn&#xff0c;问你有多少种方案用1−n1-n1−n的数能组成nnn&#xff0c;数的使用次数无限制。 n≤120n\le120n≤120 思路&#xff1a; 考虑构造母函数。 对于111构造出来的母函数为1xx2x3....…

基于Masstransit实现Eventbus的功能

Masstransit 是一个非常优秀的基于消息进行通信的分布式应用程序框架&#xff0c;详情参考官网。在介绍AA.ServiceBus之前&#xff0c;先介绍下几个概念.分布式分布式系统如何定义&#xff1f;这里引用一下Distributed Systems Concepts and Design(Third Edition)中的一句话&a…

HDU - 6975 Forgiving Matching FFT匹配字符串

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你两个串a,ba,ba,b长度分别为n,mn,mn,m&#xff0c;你需要输出m1m1m1个数&#xff0c;第iii个数表示当允许有i−1i-1i−1个数可以不匹配时aaa中长度为mmm的子串与bbb匹配的数量&#xff0c;匹配的意思就是…

微软解释为什么Rust是系统编程的最佳选择

上周&#xff0c;MSRC&#xff08;微软安全响应中心&#xff09;透露出拥抱 Rust 的打算&#xff0c;随后他们将这个话题扩展为一个系列&#xff0c;进一步阐述了使用安全的系统编程语言的的必要性&#xff0c;以及选择 Rust 的原因。在该系列最新一篇文章中&#xff0c;MSRC 团…

HDU - 6982 J - Road Discount wqs二分 + 模型转换 + 优化

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个nnn个点mmm条边的图&#xff0c;每个边有一个代价以及折扣价&#xff0c;你需要输出nnn行&#xff0c;第iii行代表你可以选i−1i-1i−1条边使其变成优惠价&#xff0c;问每次的最小生成树的代价是多…

你可能不知道的Docker资源限制

本篇内容涉及Docker的内存与CPU限制&#xff0c;可以用于在实际开发中为指定容器设置限制最大使用的资源量&#xff0c;预计阅读时间为5分钟。01—What is 资源限制&#xff1f;默认情况下&#xff0c;容器是没有资源限制的&#xff0c;它会尽可能地使用宿主机能够分配给它的资…

2021牛客暑期多校训练营4 E - Tree Xor 线段树 + 拆分区间

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一棵树&#xff0c;每个点原本都有一个权值wiw_iwi​&#xff0c;但是你只知道相邻两个点之间的wu⊕wvw_u\oplus w_vwu​⊕wv​&#xff0c;问你有多少种w1,2,...,nw_{1,2,...,n}w1,2,...,n​ n≤1e5,wi…

东南亚的IT公司,我劝你善良!

来源公众号&#xff1a;半佛仙人&#xff08;ID&#xff1a;banfoSB&#xff09;“真的救我一条‘狗命’&#xff0c;可以吗&#xff0c;谢谢您了&#xff0c;我真的撑不住了。”5月3日&#xff0c;小巴在朋友圈看到这条信息&#xff0c;附着一张长图&#xff0c;定位&#xff…

2021牛客暑期多校训练营4 B - Sample Game 期望dp\生成函数

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个生成器&#xff0c;每次生成1−n1-n1−n其中的某个数的概率为pip_ipi​&#xff0c;生成的规则如下&#xff1a; (1)(1)(1)随机生成一个数加入集合。 (2)(2)(2)判断生成的数是否是集合中的最大值&am…