首页 > 其他分享 >bzoj 3091 城市旅行

bzoj 3091 城市旅行

时间:2023-03-25 15:01:11浏览次数:57  
标签:旅行 ch bzoj 3091 Submit Input lsum include 翻转



3091: 城市旅行


Time Limit: 10 Sec   Memory Limit: 128 MB

Submit: 1697  

Solved: 565

[Submit][Status][Discuss]


Description



Input



Output



Sample Input


4 5
1 3 2 5
1 2
1 3
2 4
4 2 4
1 2 4
2 3 4
3 1 4 1
4 1 4


Sample Output


16/3
6/1


HINT


对于所有数据满足 1<=N<=50,000 1<=M<=50,000 1<=Ai<=10^6 1<=D<=100 1<=U,V<=N


Source


wyx528命题







【分析】

Congratulation!bzoj再度爆炸!稳定点会怎样哦!宝宝要做题(ㄒoㄒ)


嗯...直接放出QQQ大爷的题解   javascript:void(0)

注意一点,翻转区间的时候也要翻转 lsum[x]和rsum[x]...

本题的翻转标记必须立即生效,因为反转标记还会影响lsum和rsum

由于判断opt==3的时候直接忽略了后面读入的w所以WA到cry


【代码】

#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=50005;
int n,m,w,opt,top;
int ch[mxn][2],f[mxn],rev[mxn],st[mxn];
ll size[mxn],L[mxn],R[mxn],sum[mxn],exp[mxn],val[mxn],add[mxn];
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<<1)+(x<<3)+ch-'0',ch=getchar();
	return x*f;
}
inline bool isroot(int x) {return ch[f[x]][0]!=x && ch[f[x]][1]!=x;}
inline int get(int x) {return ch[f[x]][1]==x;}
inline void update(int x)
{
	int l=ch[x][0],r=ch[x][1];
	size[x]=size[l]+size[r]+1;
	sum[x]=sum[l]+sum[r]+val[x];
	L[x]=L[l]+(size[l]+1)*(val[x]+sum[r])+L[r];
	R[x]=R[r]+(size[r]+1)*(val[x]+sum[l])+R[l];
	exp[x]=exp[l]+exp[r]+(size[r]+1)*L[l]+(size[l]+1)*R[r]+(size[l]+1)*(size[r]+1)*val[x];
}
inline void ope(int x,ll c)
{
	if(!x) return;
	int l=ch[x][0],r=ch[x][1];
	sum[x]+=size[x]*c;
	val[x]+=c,add[x]+=c;
	L[x]+=c*size[x]*(size[x]+1)/2;
	R[x]+=c*size[x]*(size[x]+1)/2;
	exp[x]+=c*size[x]*(size[x]+1)*(size[x]+2)/6;
}
inline void reverse(int x)
{
	if(!x) return;
	rev[x]^=1;
	swap(L[x],R[x]);
	swap(ch[x][0],ch[x][1]);
}
inline void pushdown(int x)
{
	int l=ch[x][0],r=ch[x][1];
	if(rev[x]) reverse(ch[x][0]),reverse(ch[x][1]);
	if(add[x]) ope(ch[x][0],add[x]),ope(ch[x][1],add[x]);
	rev[x]=add[x]=0;
}
inline void rotate(int x)
{
	pushdown(x);
	int fa=f[x],fafa=f[fa],which=get(x);
	if(!isroot(fa)) ch[fafa][ch[fafa][1]==fa]=x;f[x]=fafa;
	ch[fa][which]=ch[x][which^1],f[ch[fa][which]]=fa;
	ch[x][which^1]=fa,f[fa]=x;
	update(fa),update(x);
}
inline void splay(int x)
{
	st[top=1]=x;
	for(int i=x;!isroot(i);i=f[i]) st[++top]=f[i];
	for(int i=top;i;i--) pushdown(st[i]);
	for(int fa;!isroot(x);rotate(x))
	  if(!isroot(fa=f[x])) rotate(get(x)==get(fa)?fa:x);
}
inline void access(int x)
{
	for(int y=0;x;y=x,x=f[x])
	  splay(x),ch[x][1]=y,update(x);
}
inline void makeroot(int x)
{
	access(x),splay(x),reverse(x);
}
inline void split(int x,int y)
{
	makeroot(x),access(y),splay(y);
}
inline int find(int x)
{
	access(x),splay(x);
	while(ch[x][0]) x=ch[x][0];
	return x;
}
inline void link(int x,int y)
{
	makeroot(x),f[x]=y;
//	int i;fo(i,0,n) printf("father[%d]=%d\n",i,f[i]);
}
inline void cut(int x,int y)
{
	split(x,y);
	ch[y][0]=f[x]=0;
}
inline ll gcd(ll x,ll y) {return y==0?x:gcd(y,x%y);}
inline void solve(int x,int y)
{
	if(find(x)!=find(y))
	{
		printf("-1\n");return;
	}
	split(x,y);
	ll a=exp[y],b=size[y]*(size[y]+1)/2;
	ll tmp=gcd(a,b);
	printf("%lld/%lld\n",a/tmp,b/tmp);
}
int main()
{
	int i,j,k,u,v;
	n=read(),m=read();
	fo(i,1,n)
	  size[i]=1,L[i]=R[i]=sum[i]=exp[i]=val[i]=read();
	fo(i,2,n)
	  u=read(),v=read(),link(u,v);
	while(m--)
	{
		opt=read(),u=read(),v=read();
		if(opt==1 && find(u)==find(v)) cut(u,v);
		if(opt==2 && find(u)!=find(v)) link(u,v);
		if(opt==3)
		{
			w=read();
			if(find(u)==find(v)) split(u,v),ope(v,(ll)w);
		}
		if(opt==4) solve(u,v);
	}
	return 0;
}
/*
4 1
1 3 2 5
1 2
1 3
2 4
4 3 2
*/



标签:旅行,ch,bzoj,3091,Submit,Input,lsum,include,翻转
From: https://blog.51cto.com/u_15967757/6149508

相关文章

  • bzoj 2006 [NOI2010] 超级钢琴 线段树求区间极值+优先队列
    挺神奇的一道题,唯一想不通的是为什么放在主席树的题单里..首先暴力找出所有的合法区间显然是不可能的。考虑怎么贪心,假如固定每个L作为左端点,那么合法的区间就是[L+l-1,L......
  • 「BZOJ3864」Hero meet devil 题解
    简要题意给你一个只由\(AGCT\)组成的字符串\(S\),对于每个\(0\leqi\leq|S|\),问有多少个只由\(AGCT\)组成的长度为\(m\)的字符串\(T\),使得\(LCS(S,T)=i\)SOLU......
  • bzoj 3101 N 皇后
    线性构造出一个解。#include<cstdio>#include<iostream>voidsolve(intn){if((n>>1)%2==0){for(inti=2;i<=n;i+=2)......
  • BZOJ #3353. [IOI2009] Archery
    这是一篇大概和题解不一样的做法。首先一个平凡的转化是将我们要操作的这个数看作\(0\),大于这个数的看作\(1\),小于的看作\(-1\),则原来的\(2n\)个数转化成对\(3\)......
  • 【磐河旅行】之酒店API接口对接实录
    1、项目需求概述:通过对接第三方磐河旅行的酒店API接口实现在我们的APP、微信小程序、H5上可提供用户酒店查询、酒店预订、退订等功能。效果如下图:  2、酒店接口功......
  • BZOJ 2870 最长道路
    BZOJ2870最长道路题意给定一棵\(n\)个节点的树,求树上一条链,使得链的长度乘链上所有点中最小权值所得的积最大\(n\le5\times10^4\)链长度是链上点的个数题面做......
  • P5416 [CTSC2016]时空旅行 题解
    首先题中的\(y,z\)好像没啥用……首先对于每一次询问,要求\(\min((x_0-x_i)^2+c_i)\)设\((x_0-x_i)^2+c_i=ans\)。那么\(x_0^2+x_i^2-2x_0x_i+c_i=ans\)所以\(x_0......
  • BZOJ 4145 [AMPPZ2014]The Prices (状压DP)
    题意你要购买商店,你到第i家商店的路费为,在第家商店购买第种物品的费用为,求最小总费用。分析很容易定义出状态,表示到第行,买的物品情况为的最小费用。按照往常的套路是转移时......
  • [bzoj 4176] Lucas的数论 (杜教筛 + 莫比乌斯反演)
    题面设为的约数个数,给定,求题目分析有这样一个结论这道题就是下面这道题的数据增强版,那么这个结论的证明就不再赘述,请自行查看下面的(蒟蒻)博客​​传送门:[SDOI2015][bz......
  • [bzoj 2693] jzptab & [bzoj 2154] Crash的数字表格 (莫比乌斯反演)
    题目描述组数据,给出,,求题目分析直接开始变换,假设N<M总算推完了…此时只需要线性筛出,然后处理的前缀和而可以出利用整除分块优化,时间复杂度为ACcode([bzoj2693]j......