求所有可能联通块的第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. Vb.net MakeLong MAKELPARAM 合并整数代码

    Function MAKELPARAM(wLow As UShort, wHigh As UShort) As UInteger Return wHigh * &H10000 + wLow E ...

  2. Java_基础篇(数组排序)

    Java_基础之数组排序(从小到大) 1.冒泡排序: 冒泡排序可以写成两层循环. 每次循环将最大的数值交换到数组的最后一个. 每排序完一次,后面就少比较一次.所以二层循环的判断条件写成:arry.le ...

  3. Springboot2注解使用Mybatis动态SQL

    1.简单SQL使用 //从***数据表获取统计数据 @Select("select count(*) from issues where issue_type = #{type}" ...

  4. Nginx + Keepalived实现应用高可用负载均衡功能

    说明:此处仅介绍 Keepalived 实现nginx负载均衡器的高可用,关于nginx介绍和负载均衡实现可查看我的另两篇博文 Nginx负载均衡 和 Nginx配置了解 应用背景:实现高可用,避免单 ...

  5. Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll

    Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll 在使用Anaconda创建一个虚拟环境出来,然后安装了scikit-learn.nump ...

  6. Android 之文件夹排序

    按文件名排序 /** * 按文件名排序 * @param filePath */ public static ArrayList<String> orderByName(String fi ...

  7. Python网络爬虫-信息标记

    信息标记的三种形式: XML(扩展标记语言) JSON(js中面向对象的信息表达形式,由类型的(string)键值对组成) "name":"北京理工大学" YA ...

  8. Centos6搭建vsftpd

    CentOS 6.5下安装Vsftp,虚拟用户一.安装:1.安装Vsftpd服务相关部件:[root@localhost ~]# yum install vsftpd*Loaded plugins: ...

  9. Docker-Docker-compose应用

    Docker-compose是用来定义和运行多容器应用的工具,它是独立于docker存在的,需要单独安装.实际应用场景中,我们的应用可能被打包运行在不同的容器里面,例如一个常规的web应用可能会涉及到 ...

  10. SQL Server(1)数据库基础

    一.数据库能够做什么 1.存储大量的数据. 2.保持数据信息的一致.完整. 3.共享和安全. 4.通过组合分析,产生新的有用信息. 二.数据库的基本概念 1.数据库就是“数据”的“仓库”. 2.数据库 ...