首页 > 其他分享 >luogu P4565 [CTSC2018]暴力写挂

luogu P4565 [CTSC2018]暴力写挂

时间:2022-12-26 20:00:20浏览次数:71  
标签:tmp P4565 int luogu st CTSC2018 sh && define

题面传送门

神tm部分分可过。

首先这个式子先两倍变成\(d_x+d_y+dist(x,y)-2d'_{LCA(x,y)}\)

如果我们按照情报中心那题的方法,枚举\(LCA(x,y)\),将\(d_x\)看成\(x\)的点权,\(d_y\)看成\(y\)的点权,合并第一棵树上最远点对,那么恭喜你,应该得到40pts,原因是用两个点维护最远点对只能在权值为正的情况下做。

那为什么是应该呢?因为在这道题里它过了……

正确做法应该是在第一棵树上点分,前面的\(d_x+d_y+dist(x,y)\)就可以转化成一个两个点独立的贡献,这时候将这些点在第二棵树上建虚树,在LCA处合并答案即可。

注意子树内不能算答案,因此要记录颜色,并要保留最大值和颜色不同的次大值。

时间复杂度\(O(n\log^2 n)\)。

code:

#include<bits/stdc++.h>
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((m)*(x-1)+(y))
#define R(n) (rnd()%(n))
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using ll=long long;using db=double;using lb=long db;using ui=unsigned;using ull=unsigned ll;
using namespace std;const int N=4e5+5,M=(1<<20)+5,K=1e5+5,mod=998244353,Mod=mod-1;const ll INF=1e18+7;const db eps=1e-5;mt19937 rnd(time(0));
struct IO{
    static const int S=1<<21;
    char buf[S],*p1,*p2;int st[105],Top;
    ~IO(){clear();}
    inline void clear(){fwrite(buf,1,Top,stdout);Top=0;}
    inline void pc(const char c){Top==S&&(clear(),0);buf[Top++]=c;}
    inline char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    inline IO&operator >> (char&x){while(x=gc(),x==' '||x=='\n'||x=='\r');return *this;}
    template<typename T>inline IO&operator >> (T&x){
        x=0;bool f=0;char ch=gc();
        while(ch<'0'||ch>'9'){if(ch=='-') f^=1;ch=gc();}
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=gc();
        f?x=-x:0;return *this;
    }
    inline IO&operator << (const char c){pc(c);return *this;}
    template<typename T>inline IO&operator << (T x){
        if(x<0) pc('-'),x=-x;
        do{st[++st[0]]=x%10,x/=10;}while(x);
        while(st[0]) pc('0'+st[st[0]--]);return *this;
    }
}fin,fout;
int n,m,k,x,y,z,col[N],B[N],Bh;ll Ans,W1[N],W2[N],Sum[N];
struct Edge{int to,w;};vector<Edge> S1[N],S2[N];vector<int> G[N];
namespace ER{
	int st[N],sh,Id[N*2][20],d[N],lg[N*2],Bg[N],Dh,Df[N*2],Fl[N],f[N][2];
	void Make(int x,int La){Df[Bg[x]=++Dh]=x;d[x]=d[La]+1;for(Edge i:S2[x]) i.to^La&&(W2[i.to]=W2[x]+i.w,Make(i.to,x),Df[++Dh]=x);}
	void BD(){
		int i,j;Make(1,0);for(i=2;i<=Dh;i++) lg[i]=lg[i/2]+1;
		for(i=Dh;i;i--){
			for(Id[i][0]=Df[i],j=1;i+(1<<j)-1<=Dh;j++) Id[i][j]=(d[Id[i][j-1]]<d[Id[i+(1<<j-1)][j-1]]?Id[i][j-1]:Id[i+(1<<j-1)][j-1]);
		}
	}
	int LCA(int x,int y){x=Bg[x];y=Bg[y];x>y&&(swap(x,y),0);int D=lg[y-x+1];return d[Id[x][D]]<d[Id[y-(1<<D)+1][D]]?Id[x][D]:Id[y-(1<<D)+1][D];}
	bool cmp(int x,int y){return Bg[x]<Bg[y];}void con(int x,int y){G[x].PB(y);}
	void dfs(int x){
		if(Fl[x]) f[x][0]=x;for(int i:G[x]){
			dfs(i);
			for(int j=0;j<2;j++) for(int h=0;h<2;h++) if(f[x][j]&&f[i][h]&&col[f[x][j]]^col[f[i][h]]) Ans=max(Ans,Sum[f[x][j]]+Sum[f[i][h]]-2*W2[x]);
			for(int j=0;j<2;j++) if(f[i][j]){
				if(!f[x][0]) f[x][0]=f[i][j];
				else if(Sum[f[i][j]]>Sum[f[x][0]]) col[f[i][j]]^col[f[x][0]]&&(f[x][1]=f[x][0]),f[x][0]=f[i][j];
				else if(!f[x][1]&&col[f[i][j]]^col[f[x][0]]) f[x][1]=f[i][j];
				else if(Sum[f[i][j]]>Sum[f[x][1]]&&col[f[i][j]]^col[f[x][0]]) f[x][1]=f[i][j];
			}
		}
	} 
	void Cl(int x){Fl[x]=0;f[x][0]=f[x][1]=0;for(int i:G[x]) Cl(i);G[x].clear();}
	void GA(){
		int i,j;for(i=1;i<=Bh;i++) Fl[B[i]]=1;B[++Bh]=1;sort(B+1,B+Bh+1,cmp);Bh=unique(B+1,B+Bh+1)-B-1;
		st[sh=1]=1;for(i=2;i<=Bh;i++){
			int Ls=LCA(st[sh],B[i]);while(sh>1&&d[st[sh-1]]>=d[Ls]) con(st[sh-1],st[sh]),sh--;
			if(st[sh]^Ls) con(Ls,st[sh]),st[sh]=Ls;st[++sh]=B[i];
		}while(sh>1) con(st[sh-1],st[sh]),sh--; dfs(1);Cl(1);
	}
}
struct yyy{int to,w,z;};struct ljb{int head,h[N];yyy f[N*2];void add(int x,int y,int z){f[++head]=(yyy){y,z,h[x]};h[x]=head;}}s;
void Make(int x,int La){for(Edge i:S1[x]) i.to^La&&(W1[i.to]=W1[x]+i.w,Make(i.to,x),0);} 
namespace TDQ{
	int Ct,Rt,Si[N],f[N],vis[N];
	void GI(int x,int La){Ct++;yyy tmp;for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],tmp.to^La&&!vis[tmp.to]&&(GI(tmp.to,x),0);}
	void DP(int x,int La){Si[x]=1;f[x]=0;yyy tmp;for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],tmp.to^La&&!vis[tmp.to]&&(DP(tmp.to,x),Si[x]+=Si[tmp.to],f[x]=max(f[x],Si[tmp.to]));f[x]=max(f[x],Ct-Si[x]);f[x]<f[Rt]&&(Rt=x);}
	void Ins(int x,int La,int w){B[++Bh]=x;col[x]=w;yyy tmp;for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],tmp.to^La&&!vis[tmp.to]&&(Sum[tmp.to]=Sum[x]+tmp.w,Ins(tmp.to,x,w),0);Sum[x]+=W1[x];Ans=max(Ans,Sum[x]+Sum[Rt]-2*W2[ER::LCA(x,Rt)]);}
	void GA(int x){
		Ct=0;GI(x,0);f[Rt=0]=1e9;DP(x,0);vis[x=Rt]=1;Ans=max(Ans,2*(W1[x]-W2[x]));yyy tmp;
		Bh=0;int Pt=0;Sum[x]=W1[x];for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],!vis[tmp.to]&&(Sum[tmp.to]=tmp.w,Ins(tmp.to,x,++Pt),0);
		ER::GA();Sum[x]=0;for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],!vis[tmp.to]&&(GA(tmp.to),0);
	}
} 
int main(){
	freopen("wronganswer.in","r",stdin);freopen("wronganswer.out","w",stdout);
	int i,j;scanf("%d",&n);for(i=1;i<n;i++) fin>>x>>y>>z,S1[x].PB((Edge){y,z}),S1[y].PB((Edge){x,z}),s.add(x,y,z),s.add(y,x,z);
	for(i=1;i<n;i++) fin>>x>>y>>z,S2[x].PB((Edge){y,z}),S2[y].PB((Edge){x,z});
	Ans=-INF;ER::BD();Make(1,0);TDQ::GA(1);printf("%lld\n",Ans/2); 
}

标签:tmp,P4565,int,luogu,st,CTSC2018,sh,&&,define
From: https://www.cnblogs.com/275307894a/p/17006718.html

相关文章

  • luogu P4775 [NOI2018] 情报中心
    题面传送门牛逼题,第一步转化都想不到。首先题目要求的是选出两条路径\((x_1,y_1),(x_2,y_2)\)满足有交,并且并的部分减去\(w_1+w_2\)最大。不妨假设\(p_1\)是\(x_1\)与\(......
  • luogu
    1973(DP,双指针)注意:题目中的区间\((l,r)\)是开区间!\(pre(i,j)\)表示前\(i\)个位置,某个地点选了\(j\)个活动,另一个地点所能选的活动数量的最大值。\(suf(i,j)\)表......
  • luoguP5383 普通多项式转下降幂多项式 题解
    学习了bztMinamoto大佬的做法,希望这篇题解可以使得那个方法更加易于理解。既然下降幂多项式转普通多项式可以采取分治\(\operatorname{NTT}\),那么可以猜测逆过来也可以......
  • luoguP2254 [NOI2005]瑰丽华尔兹 题解
    传送门题意给定\(n\)行\(m\)列的矩阵和钢琴的初始位置\((x,y)\),给定\(k\)个时间段,在每个时间段内钢琴会向给定方向(上/下/左/右)滑动,\(1\)秒移动\(1\)个单位长度......
  • Luogu4194 / LOJ115 - 网络流 -
    题目链接:https://www.luogu.com.cn/problem/P4194题解:LOJ115是无源汇上下界可行流的板子题Luogu4194需要一定建模无源汇上下界可行流,需要求一张图的流函数,使得满足流......
  • Luogu 省选计划 #1
    整体二分CDQ分治问题2(P3527)一次模拟下雨是把所有国家的一起下了,不妨所有国家一起二分。二分定义域为时间轴,初始把所有国家都挂在\(k/2\)上,然后根据结果分别缩小......
  • luogu省选计划day1
    T1过水已隐藏T2整体二分经典题,主席树上二分也可以在二分时要算一个国家的每一个出现位置,看起来是不行的但是均摊一下没有问题使用线段树辅助计算答案T3过水已隐藏T......
  • [数学记录]Luogu4284 概率充电器
    NOIp前随机一道题来补。NOIp2022rp++题意:给定一棵树,每个点\(p_i\)概率被直接激活,每条边\(p_{\{u,v\}}\)概率被激活,被激活的点可以顺着被激活的边激活其它点,求所......
  • luogu P4465 [国家集训队] JZPSTR
    题面传送门我真的,我哭死,如果考了我当场感谢zyq。听说std是SAM+块链,我瑟瑟发抖,然后祭出了bitset大法。据说这个是叫一种Shift-And的基于位运算的字符串匹配算法,也就是说,......
  • luogu1253 [yLOI2018] 扶苏的问题 题解
    扶苏的问题题目题目描述给定一个长度为\(n\)的序列\(a\),要求支持如下三个操作:给定区间\([l,r]\),将区间内每个数都修改为\(x\)。给定区间\([l,r]\),将区间内每......