bzoj3159: 决战

呀智障选手都快忘了代码怎么打了..


做这道题干啥咧..

GDOI2017D3T4.. dwjshift说很像这道题,然后就去做了..

然后就做了半个月??


简略解法

就是两棵LCT,一棵维护树的结构,一棵维护权值,两棵树在中序遍历上映射,所以维护一下根对根的映射即可


所以要怎么Access..

对于当前点$x$,在把它旋到当前splay的根的时候可以知道它在这棵splay上的排名

然后就去找对应的那棵权值splay的排名就知道映射的是哪个了啊..

然后.. 就没有然后了吧..


下面是代码呀..

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL long long
using namespace std;
const LL Maxn = 50010;
struct node {
	LL y, next;
}a[Maxn*2]; LL first[Maxn], len;
LL _max(LL x, LL y) { return x > y ? x : y; }
LL _min(LL x, LL y) { return x < y ? x : y; }
void ins(LL x, LL y) {
	len++;
	a[len].y = y;
	a[len].next = first[x]; first[x] = len;
}
LL n, m, r;
LL p[Maxn];
LL Maxx[Maxn], Minn[Maxn], sum[Maxn], val[Maxn];
LL vfa[Maxn], fa[Maxn], sizef[Maxn], sizev[Maxn];
LL cf[Maxn][2], cv[Maxn][2];
LL revf[Maxn], revv[Maxn], la[Maxn];
LL sta[Maxn], tp;
char s[10];
void dfs(LL x) {
	p[x] = x; sizef[x] = sizev[x] = 1;
	for(LL k = first[x]; k; k = a[k].next){
		LL y = a[k].y;
		if(y == fa[x]) continue;
		fa[y] = x; vfa[y] = x;
		dfs(y);
	}
}
LL rt;
/*f*/
bool is_rootf(LL x) { return cf[fa[x]][0] != x && cf[fa[x]][1] != x; }
void push_downf(LL x) {
	if(revf[x]){
		swap(cf[x][0], cf[x][1]);
		revf[cf[x][0]] ^= 1; revf[cf[x][1]] ^= 1;
		revf[x] = 0;
	}
}
void prepf(LL x) {
	LL i; tp = 0;
	for(i = x; !is_rootf(i); i = fa[i]) sta[++tp] = i;
	sta[++tp] = i;
	for(i = tp; i >= 1; i--) push_downf(sta[i]);
}
void updatef(LL x) { sizef[x] = sizef[cf[x][0]]+sizef[cf[x][1]]+1; }
void rotatef(LL x) {
	LL y = fa[x], z = fa[y], l, r;
	if(cf[y][0] == x) l = 0; else l = 1; r = l^1;
	if(!is_rootf(y)){ if(cf[z][0] == y) cf[z][0] = x; else cf[z][1] = x; }
	fa[x] = z; fa[y] = x; fa[cf[x][r]] = y;
	cf[y][l] = cf[x][r]; cf[x][r] = y;
	updatef(y);
}
void splayf(LL x) {
	rt = x;
	prepf(x);
	while(!is_rootf(x)){
		LL y = fa[x], z = fa[y];
		if(!is_rootf(y)){
			if(is_rootf(z)) rt = z;
			if((cf[z][0] == y)^(cf[y][0] == x)) rotatef(x);
			else rotatef(y);
		} else rt = y;
		rotatef(x);
	}
	updatef(x);
}
/*v*/
bool is_rootv(LL x) { return cv[vfa[x]][0] != x && cv[vfa[x]][1] != x; }
void push_downv(LL x) {
	if(revv[x]){
		swap(cv[x][0], cv[x][1]);
		revv[cv[x][0]] ^= 1; revv[cv[x][1]] ^= 1;
		revv[x] = 0;
	}
	if(la[x] > 0){
		if(cv[x][0] > 0){
			sum[cv[x][0]] += sizev[cv[x][0]]*la[x]; val[cv[x][0]] += la[x];
			Maxx[cv[x][0]] += la[x];
			Minn[cv[x][0]] += la[x];
		la[cv[x][0]] += la[x];
		} if(cv[x][1] > 0){
			sum[cv[x][1]] += sizev[cv[x][1]]*la[x]; val[cv[x][1]] += la[x];
			Maxx[cv[x][1]] += la[x];
			Minn[cv[x][1]] += la[x];
			la[cv[x][1]] += la[x];
		}
		la[x] = 0;
	}
}
void prepv(LL x) {
	LL i; tp = 0;
	for(i = x; !is_rootv(i); i = vfa[i]) sta[++tp] = i;
	sta[++tp] = i;
	for(i = tp; i >= 1; i--) push_downv(sta[i]);
}
void updatev(LL x) {
	Maxx[x] = _max(Maxx[cv[x][0]], _max(Maxx[cv[x][1]], val[x]));
	Minn[x] = _min(Minn[cv[x][0]], _min(Minn[cv[x][1]], val[x]));
	sum[x] = sum[cv[x][0]]+sum[cv[x][1]]+val[x];
	sizev[x] = sizev[cv[x][0]]+sizev[cv[x][1]]+1;
}
void rotatev(LL x) {
	LL y = vfa[x], z = vfa[y], l, r;
	if(cv[y][0] == x) l = 0; else l = 1; r = l^1;
	if(!is_rootv(y)){ if(cv[z][0] == y) cv[z][0] = x; else cv[z][1] = x; }
	vfa[x] = z; vfa[y] = x; vfa[cv[x][r]] = y;
	cv[y][l] = cv[x][r]; cv[x][r] = y;
	updatev(y);
}
void splayv(LL x) {
	prepv(x);
	while(!is_rootv(x)){
		LL y = vfa[x], z = vfa[y];
		if(!is_rootv(y)){
			if((cv[z][0] == y)^(cv[y][0] == x)) rotatev(x);
			else rotatev(y);
		}
		rotatev(x);
	}
	updatev(x);
}
LL find_rank(LL x, LL p) {
	push_downv(x);
	if(sizev[cv[x][0]]+1 == p) return x;
	if(sizev[cv[x][0]] >= p) return find_rank(cv[x][0], p);
	else return find_rank(cv[x][1], p-sizev[cv[x][0]]-1);
}
void splay(LL x) {
	splayf(x);
	LL o = find_rank(p[rt], sizef[cf[x][0]]+1);
	splayv(o);
	p[x] = o;
}
void access(LL x) {
	LL tf = 0, tv = 0;
	while(x){
		splay(x);
		LL o = p[x];
		p[cf[x][1]] = cv[o][1];
		cf[x][1] = tf;
		cv[o][1] = tv;
		if(tv) vfa[tv] = o;
		tv = o;
		tf = x;
		x = fa[x];
	}
}
void make_root(LL x) { access(x); splay(x); revf[x] ^= 1; revv[p[x]] ^= 1; }
void getchain(LL x, LL y) { make_root(x); access(y); splay(y); }
LL getsum(LL x, LL y) { getchain(x, y); return sum[p[y]]; }
LL getmin(LL x, LL y) { getchain(x, y); return Minn[p[y]]; }
LL getmax(LL x, LL y) { getchain(x, y); return Maxx[p[y]]; }
void add(LL x, LL y, LL c) { getchain(x, y); sum[p[y]] += sizev[p[y]]*c; val[p[y]] += c; Maxx[p[y]] += c; Minn[p[y]] += c; la[p[y]] += c; }
void invert(LL x, LL y) { getchain(x, y); revv[p[y]] ^= 1; }
int main() {
	LL i, j, k;
	Maxx[0] = -0x7fffffff; Minn[0] = 0x7fffffff;
	scanf("%lld%lld%lld", &n, &m, &r);
	for(i = 1; i < n; i++){
		LL x, y;
		scanf("%lld%lld", &x, &y);
		ins(x, y); ins(y, x);
	}
	dfs(r);
	for(i = 1; i <= m; i++){
		scanf("%s", s+1);
		if(s[1] == ‘I‘ && s[3] == ‘c‘){
			LL x, y, c;
			scanf("%lld%lld%lld", &x, &y, &c);
			add(x, y, c);
		} else if(s[1] == ‘S‘){
			LL x, y;
			scanf("%lld%lld", &x, &y);
			printf("%lld\n", getsum(x, y));
		} else if(s[1] == ‘M‘ && s[2] == ‘a‘){
			LL x, y;
			scanf("%lld%lld", &x, &y);
			printf("%lld\n", getmax(x, y));
		} else if(s[1] == ‘M‘){
			LL x, y;
			scanf("%lld%lld", &x, &y);
			printf("%lld\n", getmin(x, y));
		} else {
			LL x, y;
			scanf("%lld%lld", &x, &y);
			invert(x, y);
		}
	}
	return 0;
}
时间: 2024-10-12 08:35:39

bzoj3159: 决战的相关文章

bzoj3159: 决战 树链剖分+splay

方法很简单,树剖,把区间提取出来,打翻转标记,再放回去. 注意:由于某种原因,我写的是把题目中的r忽略掉的一般情况,否则简单得多. 于是本以为写起来也很简单ovo 结果发现非常繁琐,最后写得又长跑得又慢. #include<bits/stdc++.h> #define L(t) (t)->c[0] #define R(t) (t)->c[1] #define Z(t) (L(t)->s+1) #define N 50005 #define M (s+t>>1) #

bzoj3159决战 码农题 树剖套splay

最近沉迷码农题无法自拔 首先有一个暴力的想法:对于每个重链维护一个splay,需要翻转的连起来,翻转,接回去 然后发现这样没问题... 一条链只能跨log个重链,也就只有log个splay的子树参与重排,所以一次翻转只要log^2的时间 需要维护的东西有点多 头一次在splay上维护这么多乱七八糟的东西,写错了好几遍 感觉学到不少debug技巧,也纠正了之前splay写法的一个小漏洞 话说极限数据好像和miaom拍不过啊...但是我们都A了啊 好烦啊不知道谁出锅了 1 #include <bit

张小二求职记之 单例模式(三)之决战多线程

M:上回说的多线程的单例模式会了? z;略懂 M:写一个吧 package 单例模式; public class Singleton { private static Singleton instance=null; private Singleton() { System.out.println("单例构造函数"); } public static Singleton getInstance() { if(instance==null) { instance=new Singleto

用数据找机会—《决战大数据》精粹

未来是大数据的时代,未来的竞争就是数据的竞争.以前,我们都是有问题找数据,而大数据时代,其最核心的特质则是"用数据找机会".--车品觉 <决战大数据:驾驭未来商业的利器>是我在两年前接触到的第一本关于大数据的书籍,由阿里巴巴集团副总裁车品觉所著.此书不是讲具体的大数据处理技术,而是从一个大数据运营践行者的角度来讲大数据的本质.数据处理的核心思想以及阿里巴巴数据运营的"内外三板斧".文章并非枯燥的学术性论文,作者在文中加入很多工作小案例对观点进行引出.阐述

2016中国梦新电商《决战互联网+》总裁研讨会

火人2016中国梦新电商<决战互联网+>总裁研讨会,中小企业·颠覆·创新·转型·跨界·实战·方案,完美解决互联网+体系的全网规划层.落地转型层.实战执行层等全网整体方案! 2015年的市场残酷竞争激烈,传统企业纷纷倒闭及严重萎缩,缘何而起?面临着无法抗衡的新电商趋势,观望或行动慢的企业造成身心疲惫,生意越来越难做,左右徘徊找不到出路,传统企业如何成功转型或升级? 2016年是新电商与旧电商大战之年,会造成更多的传统企业继续严重萎缩及无耐倒闭,做为总裁决策者,您还没有感觉到严重危机吗?此时此刻,

大学生领取1111购物备用金流程 决战双11

一年一度的狂欢降价节距离我们越来越近了,你是否还在忧愁,钱不够花?好多东西想买,无奈没钱啊?不要担心,快来贝多分领取111购物备用金,决战双11,想买撒就买撒. 第一步:注册.信用认证 在贝多分网站注册,并进行信用认证后,可马上下订单领取1111元购物备用金; 第二步:签署协议 当天16点之前所下的订单,当天发协议,会有专业工作人员带协议与您核实身份及签署分期协议;(会有电话先沟通签协议时间.地点,在校园内签署,无需到 校园拍照,真正做到免打扰) 第三步:支付宝转账 签完合同之后,贝多分会转账1

《决战大数据》读书笔记(一) 收集数据和使用数据要有关联

亚马逊图书买200减120,买了一堆书.第一本开始阅读的就是这本<决战大数据>. 这本书没有什么理论,定义之类的描述,基本都是个人经验和感悟,全是干货,十分适合不愿意看枯燥课本的同学.要说缺点就是,逻辑性不太清晰,更像是长者在叙事性地娓娓道来,倒是挺适合技术人员看的. 目前大数据很火,但是真正能理解其中的奥妙,能正确熟练地使用大数据的人和企业却很少. “收集数据的人不知道数据可以做什么用,使用数据的人不知道数据的来源” 这样的断层,导致数据的收集没有章法没有预见没有灵魂,而数据的使用充满了疑问

决战成败之电商售后

近日在某著名电商网站购买电子产品,收货时就发现是已经拆封的商品,当时心里一凛,果然,安装上之后,该产品不能正常使用.于是迅速查找该网站的售后服务,发现有客服电话,产品在线客服(第三方厂商?)以及直接申请退换货等渠道.首先和在线客服进行了简单的沟通,说明了实际状况之后,客服立即说直接申请换货吧.于是在网站上申请了换货服务.而稍后我又致电电话客服,想询问一下换货的具体操作流程,结果二者口径并不统一,客服人员在电话里一再强调要先由顾客送回产品,然后进行检测,再做下一步结论.那意图很明显,如果产品检测没

3星|《决战618》:京东前后台软件的架构级的介绍

决战618:探秘京东技术取胜之道(全彩) 京东前后台软件的架构级的介绍.风格接近技术演讲大会上的PPT,给出架构图,介绍软件功能. 跟阿里的<尽在双11>比起来,软件演化的历史说的太少,业务逻辑说的太少,另外几乎没有作者信息. 我是想从中看看京东的业务逻辑,看后感觉涉及到的业务逻辑有点少. 总体评价3星. 以下是书中一些内容的摘抄,#号后面是kindle电子版中的页码,[]中是我根据上下文补充的信息: 1:2004年,京东只有一组简单展示商品的网页,当时技术部门只是四五个人搭建的技术小组.京东