P3925 aaa被续

题目描述没看懂(雾)

简单解释一下:

对于节点\(u\),将子树\(u\)中的权值从大到小排序,记“权值乘排名之和”为\(u\)的贡献。

输出总贡献。


下文定义\(w[u]\)为\(u\)的权值,\(siz[u]\)为子树\(u\)的大小。

考虑每个节点对答案的贡献,看起来比较困难。

转而考虑每个权值对答案的贡献。

不难发现,如果将子树\(u\)中的节点按权值从大到小排序,那么这些点的排名依次是\(siz[u],siz[u]-1,\dots,1\)。

所以我们按权值从大到小遍历每个节点。需要统计它的贡献的节点,就是它到根节点路径上的所有节点。

遍历这些节点,在\(v\)点累加的贡献是\(siz[v]\times w[u]\),并且将\(siz[v]\)减去\(1\)。

这样,\(siz[v]\)表示的始终是\(u\)在子树\(v\)中的排名。因为我们的节点是按权值从大到小统计的。

因此我们需要支持的操作:

  • 将\(u\)到根节点路径上的\(siz\)统一减去\(1\)。
  • 统计\(u\)到根节点的\(siz\)之和(将所求的和\(\times w[u]\)累入答案即可)。

可以用树剖实现。

时间复杂度\(O(n\log^2 n)\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int N=5e5+10,P=1e9+7;
int n,head[N],fa[N],dep[N],siz[N],son[N],top[N],dfn[N],tim,w[N],idx;
ll ans;
struct edge{int nxt,to;}e[N<<1];
void add(int u,int v){e[++idx]={head[u],v},head[u]=idx;}
inline int lb(int x){return x&-x;}
struct BIT{
int s1[N],s2[N];
void chp(int x,int v){
for(int i=x;i<=n;i+=lb(i)) s1[i]+=v,s2[i]+=v*x;
}
void chr(int x,int y,int v){
chp(x,v),chp(y+1,-v);
}
int query(int x){
int ans=0;
for(int i=x;i;i-=lb(i)) ans+=(x+1)*s1[i]-s2[i];
return ans;
}
int query(int x,int y){
return query(y)-query(x-1);
}
}bit;
struct Node{
int p,w;
}p[N];
void dfs1(int u){
siz[u]=1,dep[u]=dep[fa[u]]+1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa[u]) continue;
fa[v]=u,dfs1(v),siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int t){
top[u]=t,dfn[u]=++tim,bit.chr(dfn[u],dfn[u],siz[u]);
if(!son[u]) return;
dfs2(son[u],t);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
void ch_chain(int u,int v,int iv){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
bit.chr(dfn[top[u]],dfn[u],iv);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
bit.chr(dfn[v],dfn[u],iv);
}
ll query(int u,int v){
ll ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans+=bit.query(dfn[top[u]],dfn[u]);
ans%=P;
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
ans+=bit.query(dfn[v],dfn[u]);
return ans%P;
}
signed main(){
cin>>n;
for(int i=1,u,v;i<n;i++) cin>>u>>v,add(u,v),add(v,u);
for(int i=1;i<=n;i++) cin>>w[i],p[i]={i,w[i]};
dfs1(1),dfs2(1,1);
sort(p+1,p+1+n,[](Node a,Node b){return a.w>b.w;});
for(int i=1;i<=n;i++){
(ans+=query(1,p[i].p)%P*p[i].w)%=P;
ch_chain(1,p[i].p,-1);
}
cout<<ans<<"\n";
return 0;
}

[题解]P4116 Qtree3的更多相关文章

  1. [题解]luogu P4116 Qtree3

    终于来到了Qtree3, 其实这是Qtree系列中最简单的一道题,并不需要线段树, 只要树链剖分的一点思想就吼了. 对于树链剖分剖出来的每一根重链,在重链上维护一个Set就好了, 每一个Set里存的都 ...

  2. P4116 Qtree3

    思路 可以树剖可以LCT,树剖就是每个重链开一个SET维护一下黑点的深度 非常不优美 使用LCT,在splay上二分找出需要的节点即可 代码 #include <cstdio> #incl ...

  3. 洛谷 P4116 Qtree3

    Qtree系列第三题 我是题面 读完题大概不难判断是一道树剖的题 这道题的关键是记录两种状态,以及黑点的序号(不是编号) 线段树啊当然 定义两个变量v,f,v表示距离根节点最近的黑点,默认-1,f则表 ...

  4. 洛谷P4116 Qtree3

    题目描述 给出\(N\)个点的一棵树(\(N-1\)条边),节点有白有黑,初始全为白 有两种操作: \(0\) \(i\) : 改变某点的颜色(原来是黑的变白,原来是白的变黑) \(1\) \(v\) ...

  5. 洛谷P4116 Qtree3(树剖+线段树)

    传送门 LCT秒天秒地 树剖比较裸的题了 用线段树记录一下区间的最左边的黑点的编号(因为同一条链上肯定是最左边的深度最小,到根节点距离最近) 然后记得树剖的时候肯定是越后面的答案越优,因为深度越浅 / ...

  6. 题解【QTree3】

    题目描述 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑点,若无,输出 ...

  7. luogu P4116 Qtree3

    题目描述 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑点,若无,输出 ...

  8. Qtree3题解(树链剖分(伪)+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意: 很明显吧.. 题解: 我的做法十分的暴力:树链剖分(伪)+线段树+\(set\)... ...

  9. Qtree3题解(树链剖分+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意 很易懂吧.. 题解 我的做法十分的暴力:树链剖分(伪)+线段树+ std :: set ...

  10. 【洛谷 P4116】 Qtree3 (树链剖分)

    题目链接 树剖练手题,想复习下树剖. 第一次提交\(T\)成QQC 看我 ??? 看了数据范围的确挺恶心的,我的复杂度是\(O(Mlog^2N)\)的,数据范围有三段 For 1/3 of the t ...

随机推荐

  1. 在MySQL数据库中保存布尔型数据

       在存储数据时,经常会用到"是"."否"或者"有"."无"这种数据,这种时候就要应用布尔型这种数据类型了.那如何在M ...

  2. Ribbon过滤器原理解析

    Ribbon过滤器整体看是一个矩阵构建与矩阵乘法,RocksDB中对它的实现是进行了合理的空间.时间上的优化的. 符号 整个过滤器都和矩阵计算CS=R相关,C是\(n*n\)矩阵,S是\(n*m\)矩 ...

  3. JVM 类加载过程与字节码执行深度解析

    在 Java 高级程序员面试中,类加载机制与字节码执行原理是 JVM 模块的核心考察点.本文从类加载生命周期.类加载器协作机制.字节码执行引擎及面试高频问题四个维度,结合 JVM 规范与 HotSpo ...

  4. 基于Spring AI服务,开发MCP服务

    大家好,好久没有写博客了,最近突然想写一些新的东西,如何开发mcp服务,本地如何调试. 一.项目概述 Spring AI MCP Demo 是一个基于 Spring 生态的多模块应用工程,主要围绕 A ...

  5. 在Linux下使用wxWidgets进行跨平台GUI开发(三)

    创建wxWidgets应用程序 在本文中,我们将了解创建wxWidgets应用程序所需的基础知识.首先创建一个简单的示例程序,展示如何显示图标:接着通过另一个示例演示事件的使用方法:最后探讨wxWid ...

  6. Photoshop 2025超详细保姆级下载安装教程(直装版)

    目录 一.Photoshop 2025软件简介 二.Photoshop 2025下载与安装教程(详细步骤) 三.Photoshop 2025核心功能亮点 四.Photoshop 2025常见问题与注意 ...

  7. 做stm32嵌入式的上限是做什么?薪资天花板是多少?

    作为一个在嵌入式领域摸爬滚打了近10年的老兵,看到这个问题时我的内心五味杂陈.说实话,当年24岁刚从机械专业被调剂到电子专业开始接触STM32的时候,我也曾经无数次地问过自己这个问题:做嵌入式到底能走 ...

  8. 向量数据库 Chroma 和 Milvus的使用

    一.什么是向量数据库? 向量数据库(Vector Database)是专门用来存储和检索向量数据的数据库.它广泛应用于图像搜索.推荐系统.自然语言处理等领域. 简单理解: 你给数据库一堆「特征向量」( ...

  9. 前端开发系列042-基础篇之TypeScript语言特性(二)

    这篇文章中我们将继续在语言特性方面展开探讨,主要介绍了TypeScript中流程控制结构.类以及接口等方面的内容,需要说明的是这篇文章中并不会就相关特性的细节深入展开,你能得到的将只有对它们进行的浅尝 ...

  10. bluepy ble相关安装的知识

    安装bluepy 安装失败了反正是失败了 就是运行example目录下的ble目录中的scan.py 失败了然后就在我的树莓派板子上运行了 https://raspberrypi.stackexcha ...