求所有可能联通块的第k大值的和,考虑枚举这个值:

$ans=\sum\limits_{i=1}^{W}{i\sum\limits_{S}{[i是第K大]}}$

设cnt[i]为连通块中值>=i的个数

$ans=\sum\limits_{i=1}^{W}{i\sum\limits_{S}{[cnt[i]>=K]-[cnt[i+1]>=K]}}$

$ans=\sum\limits_{i=1}^{W}{\sum\limits_{S}{[cnt[i]>=K]}}$

于是先考虑树上dp,设f[i][j][k]表示以i为根的连通块中,值>=j的数量为k的情况数

然后$ans=\sum\limits_{i=1}^{N}{\sum\limits_{j=1}^{W}{\sum\limits_{k=K}^{N}{f[i][j][k]}}}$

转移和背包类似,所以这样做是$O(N^2W)$的

考虑使用生成函数优化,设$F[i][j]=\sum{f[i][j][k]x^k}$,再设$G[i][j]=\sum{F[s][j]},i是s的祖先$

于是转移就变成了$F[i][j]*=(F[s][j]+1),G[i][j]+=G[s][j],G[i][j]+=F[i][j]$,其中s是i的孩子

同时有初值$F[i][j]=(d[i]>=j?x:1)$,答案就是G[1][*]的K~N项系数的和

然后当然不能真的去乘了..

考虑先将F和G用点值表达,最后再插回来

首先枚举x=1..N+1,然后给每个点i开动态开点的线段树维护F[i][j]和G[i][j]的值

然后用线段树合并来做对应位置的相乘和相加

具体来说,我们让线段树上的结点维护一个作用在$(f,g)$上的变换$(a,b,c,d)$,使得最终得到$(af+b,cf+d+g)$

然后也不难得到变换的乘法(有结合律但没有交换律)

然后就可以做了 复杂度我也不会分析 反正有可能跑的比暴力还慢

别忘了回收掉不用的点

 #include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
#define MP make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef long double ld;
const int maxn=,maxp=3e6;
const int P=; inline char gc(){
return getchar();
static const int maxs=<<;static char buf[maxs],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,maxs,stdin),p1==p2)?EOF:*p1++;
}
inline ll rd(){
ll x=;char c=gc();bool neg=;
while(c<''||c>''){if(c=='-') neg=;c=gc();}
while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=gc();
return neg?(~x+):x;
} struct Node{
int a,b,c,d;
Node(int _a=,int _b=,int _c=,int _d=){a=_a,b=_b,c=_c,d=_d;}
}val[maxp];
Node operator *(Node x,Node y){
return Node(1ll*x.a*y.a%P,(1ll*x.b*y.a+y.b)%P,(1ll*x.a*y.c+x.c)%P,(1ll*x.b*y.c+x.d+y.d)%P);
} int N,K,W,dan[maxn],eg[maxn*][],egh[maxn],ect;
int ch[maxp][],stk[maxp],sh,rt[maxn];
int yy[maxn]; inline void adeg(int a,int b){
eg[++ect][]=b,eg[ect][]=egh[a],egh[a]=ect;
} inline int newnode(){
int p=stk[sh--];
assert(sh>=);
ch[p][]=ch[p][]=;
val[p]=Node();
return p;
} inline void delall(int &p){
if(!p) return;
delall(ch[p][]);delall(ch[p][]);
stk[++sh]=p;p=;
} inline void pushdown(int p){
if(!ch[p][]) ch[p][]=newnode();
if(!ch[p][]) ch[p][]=newnode();
val[ch[p][]]=val[ch[p][]]*val[p];
val[ch[p][]]=val[ch[p][]]*val[p];
val[p]=Node();
} void mul(int &p,int l,int r,int x,int y,Node z){
if(!p) p=newnode();
if(x<=l&&r<=y){
val[p]=val[p]*z;
}else{
int m=(l+r)>>;pushdown(p);
if(x<=m) mul(ch[p][],l,m,x,y,z);
if(y>=m+) mul(ch[p][],m+,r,x,y,z);
}
} int merge(int &p,int &q){
if(!p||!q) return p|q;
if(!ch[p][]&&!ch[p][]) swap(p,q);
if(!ch[q][]&&!ch[q][]){
val[p]=val[p]*Node(val[q].b,,,val[q].d);
return p;
}
pushdown(p),pushdown(q);
ch[p][]=merge(ch[p][],ch[q][]);
ch[p][]=merge(ch[p][],ch[q][]);
return p;
} void dfs(int x,int f,int id){
mul(rt[x],,W,,W,Node(,,,));
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==f) continue;
dfs(b,x,id);
merge(rt[x],rt[b]);
delall(rt[b]);
}
mul(rt[x],,W,,dan[x],Node(id,,,));
mul(rt[x],,W,,W,Node(,,,));
mul(rt[x],,W,,W,Node(,,,));
} int query(int p,int l,int r){
if(!p) return ;
if(l==r) return val[p].d;
int m=(l+r)>>;pushdown(p);
return (query(ch[p][],l,m)+query(ch[p][],m+,r))%P;
} int fpow(int x,int y){
int r=;
while(y){
if(y&) r=1ll*r*x%P;
x=1ll*x*x%P,y>>=;
}return r;
} int l[maxn],tmp[maxn],ans[maxn];
void calc(){
l[]=;
for(int i=;i<=N+;i++){
for(int j=i-;j>=;j--){
l[j+]=(l[j+]+l[j])%P;
l[j]=-1ll*i*l[j]%P;
}
}
for(int i=;i<=N+;i++){
int ib=-fpow(i,P-);
tmp[]=1ll*l[]*ib%P;
for(int j=;j<=N;j++){
tmp[j]=1ll*(l[j]-tmp[j-])*ib%P;
}
int k=,x=;
for(int j=;j<=N;j++){
k=(1ll*x*tmp[j]+k)%P;
x=1ll*x*i%P;
}
k=1ll*fpow(k,P-)*yy[i]%P;
for(int j=;j<=N;j++){
ans[j]=(1ll*tmp[j]*k+ans[j])%P;
}
}
} int main(){
//freopen("","r",stdin);
N=rd(),K=rd(),W=rd();
for(int i=;i<=N;i++) dan[i]=rd();
for(int i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}
for(int i=;i<maxp-;i++) stk[++sh]=i; for(int i=;i<=N+;i++){
dfs(,,i);
yy[i]=query(rt[],,W);
delall(rt[]);
}
calc();
int a=;
for(int i=K;i<=N;i++) a=(a+ans[i])%P;
printf("%d\n",(a+P)%P);
return ;
}

luogu4365 秘密袭击 (生成函数+线段树合并+拉格朗日插值)的更多相关文章

  1. [XJOI NOI2015模拟题13] C 白黑树 【线段树合并】

    题目链接:XJOI - NOI2015-13 - C 题目分析 使用神奇的线段树合并在 O(nlogn) 的时间复杂度内解决这道题目. 对树上的每个点都建立一棵线段树,key是时间(即第几次操作),动 ...

  2. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...

  3. BZOJ 3307: 雨天的尾巴( LCA + 线段树合并 )

    路径(x, y) +z : u处+z, v处+z, lca(u,v)处-z, fa(lca)处-z, 然后dfs一遍, 用线段树合并. O(M log M + M log N). 复杂度看起来不高, ...

  4. BZOJ2733 [HNOI2012]永无乡 【线段树合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. bzoj 2243 [SDOI2011]染色(树链剖分+线段树合并)

    [bzoj2243][SDOI2011]染色 2017年10月20日 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询 ...

  6. bzoj3702二叉树 线段树合并

    3702: 二叉树 Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 600  Solved: 272[Submit][Status][Discuss] ...

  7. BZOJ_2212_[Poi2011]Tree Rotations_线段树合并

    BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...

  8. B20J_2733_[HNOI2012]永无乡_权值线段树合并

    B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...

  9. BZOJ_3307_雨天的尾巴_线段树合并+树上差分

    BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...

随机推荐

  1. 折腾Java设计模式之观察者模式

    观察者模式 Define a one-to-many dependency between objects where a state change in one object results in ...

  2. Django学习之十: staticfile 静态文件

    目录 Django学习之十: staticfile 静态文件 理解阐述 静态文件 Django对静态文件的处理 其它方面 总结 Django学习之十: staticfile 静态文件 理解阐述     ...

  3. 在docker中初次体验.net core 2.0

    .net core的跨平台有了Linux,不能没有docker……网上的系列文章一大推,特别是docker还有了中文官网:https://www.docker-cn.com/ .上面说的很清楚了,这里 ...

  4. window模拟linux环境-cygwin安装

    cygwin是一个在windows平台上运行的unix模拟环境,它对于学习unix/linux操作环境,或者从unix到windows的应用程序移植,非常有用.通过它,你就可以在不安装linux的情况 ...

  5. 一起学Android之ProgressBar

    本文简述在Android开发中进度条(ProgressBar)的常见应用,仅供学习分享使用. 概述 在Android开发中,进度条的使用场景有很多,如播放电影时可拖动的观看进度条,评分时使用的评分条, ...

  6. Powershell-获取MAC地址对应IP信息

    因业务需要在DHCP服务器上绑定设备MAC,提示"指定的IP地址或硬件地址正被其他客户端使用",与业务同事沟通之前该设备做过地址保留,具体对应地址遗忘了. 问题描述: a.按照用户 ...

  7. Linux - 微软无线鼠标滚动过快问题

    Linux - 微软无线鼠标滚动过快问题 使用了一段时间的 Manjaro , 感觉相当不错, 但有一个蛋疼的地方就是每次滚动鼠标滚轮, 都会切换一页以上的页面, 总是有一部分看不到. 之前以为是 L ...

  8. Windows Server(r12) - 配置 MySQL 远程访问

    Windows Server(r12) - 配置 MySQL 远程访问 工作主要为两部分, 一部分是 Windows 防火墙, 一部分是 MySQL 自身 Windows 端口远程访问 其实就是在 W ...

  9. 浅析C#中new、override、virtual关键字的区别

    Virtual : virtual 关键字用于修饰方法.属性.索引器或事件声明,并使它们可以在派生类中被重写. 默认情况下,方法是非虚拟的.不能重写非虚方法. virtual 修饰符不能与 stati ...

  10. python已经感觉到放弃接近的day08

    居然能超过一个星期,我甚至都有点佩服我自己了,今天有两个新的知识点,一个简单一个难,先从简单的开始入手吧,进制,进制分为4种,2进制,8进制,10进制,16进制,一般最常用的就是10进制了,计算机用的 ...