「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 * derta
    outside : a * derta

    all -> a * derta
    inside -> (b-a) * derta
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
#include<iostream>
#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<int> 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]<dep[to[o<<1]]) p=to[o<<1];

	update(0,dfn[p],derta),update(0,dfn[p]+siz[p],-derta);

	for(int i=1,a,b;i<=200;i++) if(id[i].size()){
        a=Get(i,dfn[p]+siz[p]-1)-Get(i,dfn[p]-1),b=id[i].size()-a;
        update(i,1,a*derta),update(i,dfn[p],(b-a)*derta),update(i,dfn[p]+siz[p],(a-b)*derta);
	}
}

inline ll calc(int qz,int p){
	ll an=0;

	for(int i=1;i<bl[qz];i++) an+=query(i,dfn[p]);

	for(int i=qz;i;i--){
		an+=query(0,dfn[i])+query(0,dfn[p])-2ll*query(0,dfn[LCA(p,i)]);
		if(bl[i]!=bl[i-1]) break;
	}

	return an;
}

inline void prework(){
	Fdfs(1,0),Sdfs(1,1);

	for(int i=1;i<=n;i++){
		bl[i]=(i-1)/1000+1;
		id[bl[i]].pb(dfn[i]);
	}
	for(int i=1;i<=200;i++) sort(id[i].begin(),id[i].end());

	for(int i=1;i<n;i++) Maintain(i,val[i<<1]);
}

inline void solve(){
	const int ha=n;

	while(m--){
        scanf("%s",s);
        if(s[0]==‘m‘){
        	uu=read(),vv=read();
        	if(T) uu^=ans,vv^=ans;

        	Maintain(uu,vv-val[uu<<1]),val[uu<<1]=vv;
		}
		else{
			uu=read(),vv=read(),ww=read();
			if(T) uu^=ans,vv^=ans,ww^=ans;

			ans=calc(vv,ww)-calc(uu-1,ww);

			W(ans),puts(""),ans%=ha;
		}
	}
}

int main(){
//	freopen("tree.in","r",stdin);
//	freopen("tree.out","w",stdout);

	n=read(),m=read(),T=read();

	for(int i=1;i<n;i++){
		uu=read(),vv=read(),ww=read();
		add(uu,vv,ww),add(vv,uu,ww);
	}

	prework();

	solve();

	return 0;
}

原文地址:https://www.cnblogs.com/JYYHH/p/9193078.html

时间: 2024-11-05 12:33:29

「2018山东一轮集训」 Tree的相关文章

「2018山东一轮集训」鸽子

窝也不知道为什么反着BFS就是对的啊QWQ #include<cstdio> #define ll long long using namespace std; const int N=2005; int n,k,m,B[2],E[2],H,T,px[N*N],py[N*N]; int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; bool M[N][N],v[N][N]; inline bool read(){ char ch=getchar(); while(ch!

loj6102 「2017 山东二轮集训 Day1」第三题

传送门:https://loj.ac/problem/6102 [题解] 贴一份zyz在知乎的回答吧 https://www.zhihu.com/question/61218881 其实是经典问题 # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> using namespace std; typedef long long ll; typed

七牛云荣获「2018 中国云计算产业领军企业」称号

12 月 20 日,以「驾驭数字化转型走进智能互联时代」为主题的 2018 中国软件大会暨首届 CIO 创新峰会在北京新世纪日航饭店举行. 作为引领中国软件和信息技术服务产业发展的风向标和产业年度盛典,会上,隆重颁发了「2018 中国云计算产业领军企业」奖项.七牛云受邀出席,凭借其在云计算服务领域取得的优异成绩,荣获「2018 中国云计算产业领军企业」称号. 七牛云荣获「2018中国云计算产业领军企业」称号 中国软件大会自创办以来,一直紧跟时代步伐,把握行业热点,保持着高水准的思想内容和前沿观察

P4930「FJ2014集训」采药人的路径

题目:P4930「FJ2014集训」采药人的路径 思路: 这篇不算题解,是让自己复习的,什么都没说清楚. 很久没有写点分治了,以前为了赶课件学的太急,板子都没打对就照着题解写题,导致学得很不扎实. 这道题差不多是在郭老师的指导下一点点凑出来的,还是没能自己完整写出一道题,惭愧. 这道题大意是:给出一棵边权为0/1的树,求满足以下条件的路径总数:0的个数等于1的个数,且路径上存在一点到路径两端也满足该条件. 这种求路径总数的题,可以想到用点分治. 把0看作-1,就可以转化为路径边权和为0. 如果没

读薄「Linux 内核设计与实现」(2) - 进程管理和调度

这篇文章是<读薄「Linux 内核设计与实现」>系列文章的第 II 篇,本文主要讲了以下问题:进程管理的任务.进程管理与其他模块的依赖关系.进程描述符和任务队列.进程的创建.线程的实现.进程的终止.进程调度. 0x00 进程管理的任务 进程能创建新的进程(通过复制现有进程) 确定哪个进程能拥有 CPU 接受中断并将中断导向相应的内核子系统 管理时钟硬件 当一个进程结束时释放其资源 动态装载执行模块 0x01 进程管理与其他模块的依赖关系 I 进程模块的内外界面 对用户进程提供了一组简单的系统调

【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(1)

http://www.4gamer.net/games/216/G021678/20140703095/ 新连载「实验做出的游戏图形」,是聚焦在特定游戏的图形上, 对它的结构和使用的技术解说为主旨.之前笔者连载的「西川善司的3D游戏入迷」,覆盖范围都很广,而与特定游戏强关联的技术解说,会在今后的新连载中处理. 作为纪念的第一回选择的,是Arc System Works开发的,2014年2月在街机上运作的格斗游戏「GUILTY GEAR Xrd -SIGN-」 全3D图形的GUILTY GEAR

「七天自制PHP框架」第三天:PHP实现的设计模式

往期回顾:「七天自制PHP框架」第二天:模型与数据库,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 为什么要使用设计模式? 设计模式,我的理解是为了达到"可复用"这个目标,而设计的一套相互协作的类. 感兴趣的读者可以阅读<Design Patterns: Elements of Reusable Object-Oriented Software>,四位作者(Gang of Four)在书中列举

「Rancher社区技术支持计划」全面启动

2015年6月 Rancher Labs第一次推出原始测试版Rancher 2016年3月 开源的全栈化容器管理平台Rancher正式版发布 600多个日夜 Rancher推出了共计569个版本 在全球范围内下载量超过1900万次 愈发庞大的开源社区伙伴队伍 愈发频繁的迭代和新功能发布 我们为之欣喜 也生怕因有限的精力 而无法给所有用户更好的技术支持 为了为Rancher用户创造更好的使用体验 为了回应您提出的每一个问题 解决您遇见的每一个故障 重视您发现的每一个bug Rancher Labs

「Mobile Testing Summit China 2016」 中国移动互联网测试大会-议题征集

时至北京盛夏,一场由 TesterHome 主办的关于移动互联网测试技术的盛会正在紧锣密鼓的筹备中.只要你关注软件质量,热爱测试,期待学习,都欢迎你加入这次移动测试技术大会中和我们一起分享经验.探讨话题,结识业界朋友. 「Mobile Testing Summit China 2016」中国移动互联网测试大会 大会定位:专注移动互联网测试技术的分享会,关注移动互联网质量的有志之士的集会. 大会主旨:秉承着务实.能落地.有深度.高质量.重分享的原则与广大测试工程师做最新最实用的分享与交流,以推广新