首页 > 「2018山东一轮集训」 Tree

「2018山东一轮集训」 Tree

 

 

    为什么出题人这么毒瘤啊??!!一个分块还要带log的题非要出成n<=2*1e5。。。。。。。

    为了卡过最后两个点我做了无数常数优化,包括但不限于:把所有线段树改成 存差分的树状数组;把树剖求LCA的极小的log优化成rmq O(1)求LCA;根据测试情况手动调整siz的大小;

    但就是死也卡不过去,算了算了QWQ

 

(常规套路,先把1设成根建有根树)

 

    这个题的主要思路就是 对节点的下标分块,设 f[i][j] 为 第i个块内所有点到点j的距离和,然后看如何快速的动态维护这个玩意。。。。

    发现改动一条边权的时候,只有两个点分别位于这条边两侧的时候才会对它们之间的dis有影响。

    我们设p为边端点中更深的那个,那么也就是一个在p子树内,一个在子树外的才有影响。。。。

    于是我们对每个块开一个vector记录一下这个块内的点的dfs序集合,排完序之后就可以之间O(log)的查询某个块在一棵子树内/外的点数了。。。

    因为f[][]的第一维比较小,所以我们可以暴力枚举第一维,然后对第二维进行快速的修改。。。。。这时候发现第二维如果是存dfs序的话会更加方便(子树内可以直接进行区间修改),所以就改成下标代表dfs序啦。。。

   

    对于整块整块的一些点到某个点的距离,用上述方法就行啦。。。可以发现都是区间修改单点查询,所以用差分的树状数组可以快(可能还不止)4倍常数哦。。。

   

    查询零散的点对(i,j)之间的距离的话更加简单。。可以动态维护dis[i]表示i到根的距离(发现也是区间修改单点查询,所以可以类似上述整块的方法处理),答案就是dis[i]+dis[j]-2*dis[LCA(i,j)]。。。

 

    可能说起来不是很多吧qwq?但是要写一辈子啊QWQWQWQ。。。。

    (我美好的下午就这么没了QWQ)

    话说我把树剖求LCA改成rmq之后反而更慢了QWQ,这是什么鬼啊。。。。

 

/*inside : b * dertaoutside : a * dertaall -> a * dertainside -> (b-a) * derta
*/
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
#define pb push_back
const int maxn=200003,N=205;inline int read(){int x=0; char ch=getchar();for(;!isdigit(ch);ch=getchar());for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';return x;
}void W(ll x){ if(x>=10) W(x/10); putchar(x%10+'0');}int n,m,T,dep[maxn],siz[maxn],cl[maxn];
int F[maxn],dc,dfn[maxn],dy[maxn],son[maxn];
int bl[maxn],num,val[maxn*2],uu,vv,ww;
int hd[maxn],ne[maxn*2],to[maxn*2];
ll ans=0,f[N][maxn];
vector id[N];
char s[10];void add(const int &x,const int &y,const int &z){to[++num]=y,ne[num]=hd[x],hd[x]=num,val[num]=z;
}void update(const int &T,int x,const int &y){ for(;x<=n;x+=x&-x) f[T][x]+=(ll)y;}
ll query(const int &T,int x){ ll an=0; for(;x;x-=x&-x) an+=(ll)f[T][x]; return an;}void Fdfs(int x,int fa){F[x]=fa,siz[x]=1;for(int i=hd[x];i;i=ne[i]) if(to[i]!=fa){dep[to[i]]=dep[x]+1,Fdfs(to[i],x),siz[x]+=siz[to[i]];if(!son[x]||siz[to[i]]>siz[son[x]]) son[x]=to[i];}
}void Sdfs(int x,int tp){dfn[x]=++dc,dy[dc]=x,cl[x]=tp;if(!son[x]) return;Sdfs(son[x],tp);for(int i=hd[x];i;i=ne[i])if(to[i]!=F[x]&&to[i]!=son[x]) Sdfs(to[i],to[i]);
}inline int LCA(int a,int b){while(cl[a]!=cl[b]){if(dep[cl[a]]>dep[cl[b]]) a=F[cl[a]];else b=F[cl[b]];}return dep[a]>dep[b]?b:a;
}inline int Get(int T,int x){return upper_bound(id[T].begin(),id[T].end(),x)-id[T].begin();
}inline void Maintain(int o,int derta){int p=to[o*2-1];if(dep[p]

 

转载于:https://www.cnblogs.com/JYYHH/p/9193078.html

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • We have ZZIPlib installed.My command configure line looks like :./configure ?with-apxs ?with-curl ?with-curl-dir=/usr/local/lib ?with-gd ?with-gd-dir=/usr/local ?with-g...

  • asar Whether to package the application’s source code into an archive, using Electron’s archive format. Defaults to true. Node modules, that must be unpacked, will be d...

  • 1.      今天遇到一问题,在sles11/vxworks下编译通过,但是在hpux下失败 2.      编译错误: /usr/ccs/bin/ld:DP relative code in file /projects/xxx/DERIVED/tfa_pa32-hpux.a(tfa02_pa32-hpux.o) -share...

  •         最近买个了小本lenovo x100e,结果发现这小本没有大小写指示灯,在windows用也无妨,不过我常常用这本在ubuntu中调试linux代码,vi 常用的编辑器,熟悉的都知道,大小写很关键的,用google搜了一下,发现可以用如下方法解决:        1.  “sudo apt-get install l...

  •   修改Ubuntu的启动logo 原文链接: https://my.oschina.net/jmjoy/blog/380262     内容:   Plymouth splash screen is the initial splash screen at boot-up.Ubuntu 10.04 uses Plym...