[XSY] 绿色(圆方树、树形DP、树上差分)

绿色

题意简述

在这里插入图片描述

题解

首先,每次修改完点权后,重新考虑一遍所有路径显然是不现实的,所以我们考虑求出经过每个点的两端同色的简单路径数,这样权值和容易统计和修改。
在这里插入图片描述
接下来分析仙人掌上的简单路径性质。一条简单路径上的边,可以分为桥边环上的边过桥只有一种方法,而过同一个环有两个方向的环边可选。

现在,我们选取一个关键点,强制简单路径必须通过该点。如果关键点在一个环上,且该简单路径在该环上的第一个和最后一个点均不是关键点,那么该环只有一个方向的环边可选。

建立原仙人掌的圆方树。
如果定义方点贡献 2 种方案,圆点贡献 1 种方案,一条路径贡献方案数为所有点贡献方案数之积,那么原仙人掌上两个同色点间的路径数转化为对应圆点间的简单路径方案数

在所有的树上简单路径中,
如果它通过关键点,则贡献值为该路径的方案数;
如果它不通过关键点,但是通过关键点的某相邻方点,则贡献该路径方案数的一半。


考虑用何算法求出经过每个点的两端同色的简单路径数(记过uuu的简单路径数为coe[u]coe[u]coe[u]):

法一:暴力枚举

按题意枚举所有同色点对,可解决n≤100n≤100n100的子任务。

法二:树形DP

首先枚举每一种颜色,每次只考虑当前颜色的同色点对的贡献。
在这里插入图片描述
对于树上任意一点uuu,我们可以求出:
dp[u]=dp[u]=dp[u]= uuu的子树内当前色的圆点到uuu的路径数
up[u]=up[u]=up[u]= uuu的子树外当前色的圆点到uuu的路径数
(换根DP)
那么过uuu的简单路径数coe[u]+=(dp[u]+up[u]+1)2−dp[u]2−dp[v]2−122coe[u]+=\frac{(dp[u]+up[u]+1)^2-dp[u]^2-dp[v]^2-1^2}{2}coe[u]+=2(dp[u]+up[u]+1)2dp[u]2dp[v]212

这样可以解决n≤105,k≤5n\leq10^5,k\leq5n105,k5的子任务

优化:建虚树

处理树上询问点两两间路径的并的问题,一个常见的套路是构建询问点的虚树,因为虚树中同一条边上的点受询问点的影响一致,把这些点一起处理可大大提高效率

于是,我们构建同色点的虚树,通过前缀和,预处理虚树每条边上压缩的点贡献的方案数,作为边的方案数。

对于过虚树节点的简单路径数,可以在树形dp时直接统计出来;
对于过虚树边上压缩掉的点的简单路径数,可以利用树上差分与前缀和快速处理。

那么接下来仅需考虑 过关键点相邻的方点的路径总方案数 即可:
计算通过了每个相邻方点的路径总方案数,再减去通过了它们之间相邻边的方案数。

不难发现,上述树上差分与前缀和的方法,已经预处理了通过各边的路径方案数。

此算法时间复杂度O(nlogn)O(n log n)O(nlogn)、空间复杂度O(n)O(n)O(n)

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int inv2=(mod+1)/2;
namespace modular{int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}int dec(int a,int b){return a-b<0?a-b+mod:a-b;}int mul(int a,int b){return 1ll*a*b%mod;}void Add(int &a,int b){a=add(a,b);}void Dec(int &a,int b){a=dec(a,b);}void Mul(int &a,int b){a=mul(a,b);}
}
using namespace modular;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
const int N=1e6+10;
int n,m,k,pw[N];
int c[N],w[N];
vector<int> S[N];int cnt,head[N],to[N<<1],nxt[N<<1];
int coe[N],nd;
vector<int> e[N];
int in[N],out[N],dfn,fr[N];
bool is[N];
void addedge(int u,int v){to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
}
void build(int u,int pre){//建圆方树 in[u]=++dfn;for(int i=head[u];i;i=nxt[i]){if(!((i^1)^pre)) continue;//条件一定不能改 int v=to[i];if(!in[v]){fr[v]=u;build(v,i);//记来边而不是来点 }else if(in[v]<in[u]){++nd;e[nd].push_back(v);e[v].push_back(nd);for(int x=u;x!=v;x=fr[x]){is[x]=1;e[nd].push_back(x);e[x].push_back(nd);}}}
}int ct[N],fa[N],sz[N],son[N],dep[N],top[N];
void sub_dfs(int u,int f){in[u]=++dfn;sz[u]=1;fa[u]=f;dep[u]=dep[f]+1;for(int i=0;i<e[u].size();i++){int v=e[u][i];if(v==f) continue;ct[v]+=ct[u]+(u>n);sub_dfs(v,u);sz[u]+=sz[v];if(sz[v]>sz[son[u]]) son[u]=v;}out[u]=dfn;
}
void tp_dfs(int u,int tp){top[u]=tp;if(!son[u]) return;tp_dfs(son[u],tp);for(int i=0;i<e[u].size();i++){int v=e[u][i];if(v!=fa[u]&&v!=son[u]) tp_dfs(v,v);}
}
int LCA(int x,int y){while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);x=fa[top[x]];}return dep[x]<dep[y]?x:y;
}
bool sub(int x,int y){return in[x]<=in[y]&&in[y]<=out[x];
}int ta[N],dot[N];
//ta[u]记录过u,且过边(u,fa[u])的路径数(用树上差分求出,所以work时的ta是差分数组,u子树内的ta和才是实际路径数) 
//dot[u]记录过u,但不过边(u,fa[u])的路径数 
vector<int> G[N];
int dp[N],up[N];
//dp[u]记录u子树内当前色的圆点到u的路径数
//up[u]记录u子树外当前色的圆点到虚树上u的父亲的路径数 
bool o[N];
bool cmp(int x,int y){return in[x]<in[y];
}
void dfs1(int u){dp[u]=o[u];for(int i=0;i<G[u].size();i++){int v=G[u][i];dfs1(v);Add(dp[u],mul(pw[ct[v]-ct[u]],dp[v]));}
}
void dfs2(int u,int f){int c;if(f){c=mul(up[u],dp[u]);Mul(c,pw[ct[u]-ct[f]-(f>n)]);Add(ta[u],c);Dec(ta[f],c);Dec(dot[u],c);}c=mul(pw[ct[u]-ct[f]+(u>n)-(f>n)],up[u]);int S=mul(c,c)+o[u], all=add(dp[u],c);for(int i=0;i<G[u].size();i++){int v=G[u][i];c=mul(pw[ct[v]-ct[u]],dp[v]);Add(S,mul(c,c));}S=dec(mul(all,all),S);Mul(S,inv2);if(u>n) Mul(S,inv2);Add(dot[u],S);for(int i=0;i<G[u].size();i++){int v=G[u][i];Add(up[v],dp[u]);Add(up[v],mul(pw[ct[u]-ct[f]+(u>n)-(f>n)],up[u]));Dec(up[v],mul(pw[ct[v]-ct[u]],dp[v]));dfs2(v,u);}
}
void work(vector<int> &p){//对每种颜色的点建虚树,求解 sort(p.begin(),p.end(),cmp);static int ex[N],tim;tim++;for(int i=0;i<p.size();i++){int x=p[i];ex[x]=tim;o[x]=1;}int n=p.size(),x,y,z;for(int i=0;i+1<n;i++){int x=LCA(p[i],p[i+1]);if(ex[x]!=tim) ex[x]=tim,p.push_back(x);}sort(p.begin(),p.end(),cmp);static int s[N];int top=0;for(int i=0;i<p.size();i++){x=p[i];while(top>1&&!sub(s[top],x)){y=s[top],z=s[top-1];G[z].push_back(y);top--;} s[++top] = x; }while(top>1){y=s[top],z=s[top-1];G[z].push_back(y);top--;}dfs1(p[0]);dfs2(p[0],0);for(int i=0;i<p.size();i++){int x=p[i];up[x]=o[x]=0;G[x].clear();}p.clear();
}
void dfs(int u,int f){for(int i=0;i<e[u].size();i++){int v=e[u][i];if(v==f) continue;dfs(v,u);Add(ta[u],ta[v]);}coe[u]=mul(2,add(ta[u],dot[u]));for(int i=0;i<e[u].size();i++){int v=e[u][i];if(v!=f&&v>n) Add(coe[u],dot[v]);}
}
int main(){n=read();m=read();k=read();pw[0]=1;for(int i=1;i<=n;i++) pw[i]=add(pw[i-1],pw[i-1]);nd=n;for(int i=1;i<=n;i++){c[i]=read();S[c[i]].push_back(i);}for(int i=1;i<=n;i++) w[i]=read();cnt=1;for(int i=1;i<=m;i++){int u=read(),v=read();addedge(u,v);addedge(v,u);}build(1,0);for(int i=2;i<=n;i++){if(!is[i]){e[i].push_back(fr[i]);e[fr[i]].push_back(i);} 	}dfn=0;    sub_dfs(1,0);tp_dfs(1,1);for(int i=1;i<=k;i++) work(S[i]);dfs(1,0);for(int i=2;i<=n;i++){int x=fa[i];if(x>n){int c=add(ta[x],dot[x]);Dec(c,ta[i]);Add(coe[i],c);}}for(int i=1;i<=n;i++) Mul(coe[i],inv2);//trick:前面先计算系数的2倍,最后再/2 int ans=0;for(int i=1;i<=n;i++)Add(ans,mul(w[i],coe[i]));printf("%d\n",ans);int Q=read();for(int i=1;i<=Q;i++){int x=read(),v=read();Add(ans,mul(v,coe[x]));printf("%d\n",ans);}return 0;
} 
/*
4 5 2
1 2 1 2
1 2 3 4
1 2
1 2
2 3
2 4
3 4
1
3 1
*/

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

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

相关文章

牛客网 【每日一题】5月29日 管道取珠

链接&#xff1a; 文章目录题目描述题意&#xff1a;题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 2秒&#xff0c;其他语言4秒 空间限制&#xff1a;C/C 524288K&#xff0c;其他语言1048576K 64bit IO Format: %lld题目描述 管道取珠是小X很喜欢的一款游戏。在本…

半天搭建你的Jenkins持续集成与自动化部署系统

前言相信每一位程序员都经历过深夜加班上线的痛苦&#xff01;而作为一个加班上线如家常便饭的码农&#xff0c;更是深感其痛。由于我们所做的系统业务复杂&#xff0c;系统庞大&#xff0c;设计到多个系统之间的合作&#xff0c;而核心系统更是采用分布式系统架构&#xff0c;…

.Net业务搭配实用技术栈

前言昨天有篇文章在讨论webform的设计思路&#xff0c;我已经四五年不用webform了&#xff0c;虽然它也提供了HttpModule和httphandle来处理请求&#xff0c;提供了一般处理程序ashx来简化处理流程&#xff0c;但依然会想起它的form runatserver&#xff0c;想起注册客户端脚本…

Service Fabric 用 Powershell 部署应用到本地

前置说明安装 Service Fabric SDK&#xff0c;会在本机 C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK 生成部署脚本&#xff0c;如下图&#xff1a;用VS创建一个 Service Fabric 应用后&#xff0c;有一个部署脚本&#xff0c;位置在 [应用…

ElasticSearch入门 附.Net Core例子

1.什么是ElasticSearch?Elasticsearch是基于Lucene的搜索引擎。它提供了一个分布式&#xff0c;支持多租户的全文搜索引擎&#xff0c;它具有HTTP Web界面和无模式JSON文档。 Elasticsearch是用Java开发的&#xff0c;根据Apache许可条款作为开源发布。----来自维基百科的解释…

《.NET 性能优化》送书活动结果公布

截止到9月7日18&#xff1a;00&#xff08;规则本是12&#xff1a;00&#xff0c;忙的忘记了这事&#xff0c;18点截的图&#xff09;&#xff0c;本次送书活动《.NET 性能优化》共收到100多位同学参与回复&#xff0c;本次很多同学在看到活动的书 &#xff0c;自行就到异步社区…

hdu-2844 Coins (混合背包+二进制优化)

HDU链接 文章目录题目描述&#xff1a;题意&#xff1a;题解&#xff08;代码&#xff09;题目描述&#xff1a; 输入描述: 输出描述: For each test case output the answer on a single line. 输入 3 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0输出 8 4题意&#xff1a; 有n种硬币&…

.NET Core WebApi中实现多态数据绑定

什么是多态数据绑定&#xff1f;我们都知道在ASP.NET Core WebApi中数据绑定机制&#xff08;Data Binding&#xff09;负责绑定请求参数&#xff0c; 通常情况下大部分的数据绑定都能在默认的数据绑定器&#xff08;Binder&#xff09;中正常的进行&#xff0c;但是也会出现少…

hdu 1059 Dividing

Hdu链接 文章目录题目描述题意&#xff1a;题解&#xff1a;代码&#xff1a;题目描述 输入描述: 输出描述: 示例1 输入 1 0 1 2 0 0 1 0 0 0 1 1 0 0 0 0 0 0输出 Collection #1: Cant be divided.Collection #2: Can be divided.题意&#xff1a; 有价值分别是1~6的6种…

.Net Core应用框架Util介绍(二)

Util的开源地址https://github.com/dotnetcore/utilUtil的开源协议Util以MIT协议开源&#xff0c;这是目前最宽松的开源协议&#xff0c;你不仅可以用于商业项目&#xff0c;还能把Util的代码放进你的框架&#xff0c;放心使用。Util的命名Util这个名字看上去不怎么高大上&…

.Net架构篇:实用中小型公司支付中心设计

前言说起支付平台&#xff0c;支付宝量级的支付平台和一个小型公司的支付不可同日耳语。一个初创或刚创业一两年的公司&#xff0c;一没人力&#xff0c;二没财力的情况下&#xff0c;如果也想对接支付那怎么办呢&#xff1f;感谢支付宝和微信支付&#xff0c;两大行业巨头提供…

netcore编程之后面对不习惯的xshell黑屏部署,是时候使用jenkins自动化发布工具了...

在很久之前net还只能在windows上部署的时候&#xff0c;或许很多创业公司的朋友发布项目还都是人肉部署&#xff0c;反正windows都是可视化的界面&#xff0c;拖拖拉拉&#xff0c;开开关关还不是特别麻烦。。。现如今你的项目需要在linux上部署&#xff0c;可惜的是再也没有什…

【招聘(重庆)】新空间(重庆)科技有限公司招聘.NET Core

全新平台公司&#xff0c;技术氛围好&#xff0c;未来上升空间巨大!平台架构师薪资范围&#xff1a;15K至40K岗位职责&#xff1a;1、负责公司业务以及相关平台的架构设计、技术选型、研发工作, 参与产品架构的规划与设计&#xff1b;2、遵循总体的架构规划与规范设计项目的应用…

[XSY3320] string (AC自动机,哈希,点分治)

XSY3320 前置芝士&#xff1a;回文前缀&&borderborderborder 推荐博客 推荐博客 考虑点分治&#xff0c;问题变成求经过重心的回文路径个数。 一条经过重心的回文路径长这样&#xff1a; xxx到zzz的串与yyy到rootrootroot的串相同。 建出根到每个节点对应的串的AC自…

如何在 ASP.Net Core 中使用 Consul 来存储配置

原文: USING CONSUL FOR STORING THE CONFIGURATION IN ASP.NET CORE作者: Nathanael[译者注&#xff1a;因急于分享给大家&#xff0c;所以本文翻译的很仓促&#xff0c;有些不准确的地方还望谅解]来自 Hashicorp 公司的 Consul 是一个用于分布式架构的工具&#xff0c;可以用…

[XSY3381] 踢罐子(几何)

XSY3381 点被选为点对之一的贡献我们单独计算&#xff08;这部分贡献的总和为4n(n−1)(n−2)4n(n-1)(n-2)4n(n−1)(n−2)&#xff09;。接下来只讨论剩余部分的贡献。 先把任意三个点构成的六种选择方案合并&#xff0c;发现在外接圆周和弦之间的点每个有2的贡献&#xff0c;…

The Bottom of a Graph Poj 2553

牛客网 poj 2553 文章目录Description题意&#xff1a;题解&#xff1a;代码&#xff1a;Description We will use the following (standard) definitions from graph theory. Let V be a nonempty and finite set, its elements being called vertices (or nodes). Let E be …

关于.NET Core是否应该支持WCF Hosting的争论

本文要点本文试图回答“.NET Core 是否应该支持 Windows 通信基础&#xff08;WCF&#xff09; Hosting&#xff1f;”的问题&#xff1b;支持者论据&#xff1a;许多工程师喜欢把 WCF 作为一种编程模型&#xff0c;不希望因为迁移到 .NET Core 而产生&#xff08;机会成本&…

ASP.NET Core 2.0使用Autofac实现IOC依赖注入竟然能如此的优雅简便

初识ASP.NET Core的小伙伴一定会发现&#xff0c;其几乎所有的项目依赖都是通过依赖注入方式进行链式串通的。这是因为其使用了依赖注入 (DI) 的软件设计模式&#xff0c;代码的设计是遵循着“高内聚、低耦合”的原则&#xff0c;使得各个类与类之间的关系依赖于接口&#xff0…

连续段问题小结

一个好用的工具——析合树 oi-wiki 例题 CF526F 题意&#xff1a; 给出一个1~nnn的排列&#xff0c;问有多少个区间的值域是连续的。 题解&#xff1a; 线段树单调栈做法 分治做法 析合树做法 图论做法 CF997E 题意&#xff1a; 给出一个1~nnn的排列&#xff0c;有qqq次…