3626: [LNOI2014]LCA|动态树

这真是一道神题!!
显然需要离线来解决,再就是用到了差分的思想
以下是PoPoQQQ大爷复制gconeice的题解,说得非常详细,就不再赘述了

显然,暴力求解的复杂度是无法承受的。
考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案。观察到,深度其实就是上面有几个已标记了的点(包括自身)。所以,我们不妨把 z 到根的路径上的点全部 +1,对于 l 到 r 之间的点询问他们到根路径上的点权和。仔细观察上面的暴力不难发现,实际上这个操作具有叠加性,且可逆。也就是说我们可以对于 l 到 r 之间的点 i,将 i 到根的路径上的点全部 +1, 转而询问 z 到根的路径上的点(包括自身)的权值和就是这个询问的答案。把询问差分下,也就是用 [1, r] − [1, l − 1] 来计算答案,那么现在我们就有一个明显的解法。从 0 到 n − 1 依次插入点 i,即将 i 到根的路径上的点全部+1。离线询问答案即可。我们现在需要一个数据结构来维护路径加和路径求和,显然树链剖分或LCT 均可以完成这个任务。树链剖分的复杂度为 O((n + q)· log n · log n),LCT的复杂度为 O((n + q)· log n),均可以完成任务。至此,题目已经被我们完美解决。

动态树都码不对了真是sosad。。。因为一个y打成了x调了1H。。。本来100+行的代码各种输出中间结果成了将近200行?

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mod 201314
#define ll long long
#define N 50005
#define mx 1e9
using namespace std;
int sc()
{
    int i=0,f=1; char c=getchar();
    while(c>'9'||c<'0'){
  if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i*f;
}
struct W{
  int l,z,pos;}a[N*3];
ll sum[N],v[N],tag[N],size[N],ans[N*2];
int fa[N],ch[N][2],st[N],TI;
int n,top,cnt,q;
bool rev[N];
bool Root(int x){
  return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
bool cmp(W a,W b){
  return a.l<b.l;}
void cal(int x,ll f)
{
    v[x]+=f;
    tag[x]+=f;
    sum[x]+=size[x]*f;
}
void push_up(int x)
{
    sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+v[x];
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void push_down(int x)
{
    if(rev[x])
    {
        rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;
        swap(ch[x][0],ch[x][1]);
        rev[x]=0;
    }
    if(tag[x])
    {
        if(ch[x][0])cal(ch[x][0],tag[x]);
        if(ch[x][1])cal(ch[x][1],tag[x]);
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值