2023.3.23 日寄

2023.3.23 日寄

挑战 \(20\min\) 极限日寄+骂出题人。

越来越懒了,日寄更新频率↓/kk

一言

\(~~~~\) 在这个世界上,饱受苦难的人不一定是好人,满嘴谎话的也不一定是坏人,这个世界上有幸福存在,也有痛苦,这个世界上的绝大多数特质都可以在一个人身上共存。

\(~~~~\) 什么贪婪,自私,痛苦,压抑,短视,热情,都可以在一个人身上共存。

\(~~~~\) 还有苦难与幸福,好运与灾祸。

\(~~~~\) 人就是由这些事物所集合的存在。

\(~~~~\) 所以由我们人所组成的这个社会,它也是如此复杂的。

\(~~~~\) 无数人的祈愿在这个社会当中流转,每个人都背负着自己的祈盼在活着,痛苦的呻吟声和幸福的欢笑,每时每刻都在土地上响起。
作者:朱慈
链接:https://www.zhihu.com/question/420428840/answer/2930586287

模拟赛

\(~~~~\) 出题人你不想给分可以不给而不是把选手当狗耍。

\(~~~~\) 19/300的暴力分是个人都得流汗。还 tm 选了三道*一样长的题目。

「2021 集训队互测」序列

题意

\(~~~~\) 长为 \(n\) 的序列,每个元素都在 \([1,10^9]\) 之间。给定 \(m\) 个形如 \((i,j,k,x)\) 的信息,表示 \(a_i,a_j,a_k\) 的中位数为 \(x\)。请构造原序列或说明无解。
\(~~~~\) \(1\leq n,m\leq 10^5,1\leq x\leq 10^9\).

题解

\(~~~~\) 如果你想到了正解的算法那题目很简单,如果没想到,那一堆不知名的错解可以把你搞崩溃。

\(~~~~\) 考虑把每个数分成 \(a_i< x\)\(a_i\geq x\) 两种互斥的表达式。对于一个 \((i,j,k,x)\) 的限制,显然若 \(a_i<x\) ,则必有 \(a_j \geq x,a_k\geq x\);反之若 \(a_i\geq x\),则必有 \(a_j<x+1,a_k<x+1\)

\(~~~~\) 很显然这就是一个 2-SAT 问题了,那直接套板子。

代码
查看代码
#include <bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define mp(a,b) make_pair(a,b)
using namespace std;
template<typename T>void read(T &x)
{
    T f=1;x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
    x*=f;
}
struct node{
	int p1,p2,p3,x;
	node(){}
	node(int P1,int P2,int P3,int X){p1=P1,p2=P2,p3=P3,x=X;}
}P[5000005];
char Ty1[15],Ty2[15];
vector <int> G[5000005];
int brr[5000005],cnt;
pair<PII,int> To[5000005];
map<int,int>M1[100005],M2[100005];//小于和大于等于 
void Init(int x,int Val)
{
	if(!M1[x][Val]) M1[x][Val]=++cnt,To[cnt]=mp(mp(x,Val),1);
	if(!M2[x][Val+1]) M2[x][Val+1]=++cnt,To[cnt]=mp(mp(x,Val+1),2);
	if(!M1[x][Val-1]) M1[x][Val-1]=++cnt,To[cnt]=mp(mp(x,Val-1),1);
	if(!M2[x][Val]) M2[x][Val]=++cnt,To[cnt]=mp(mp(x,Val),2); 
}
void DEBUG(int u,int v)
{
	return;
	int pos1=To[u].first.first,X1=To[u].first.second,Type1=To[u].second;
	int pos2=To[v].first.first,X2=To[v].first.second,Type2=To[v].second;
	printf("(%d%s%d) (%d%s%d)\n",pos1,Type1==1?Ty1+1:Ty2+1,X1,pos2,Type2==1?Ty1+1:Ty2+1,X2);
}
void Connect(int p1,int p2,int p3,int x)
{
	if(M1[p1].count(x-1)&&M2[p2].count(x)) G[M1[p1][x-1]].push_back(M2[p2][x]),DEBUG(M1[p1][x-1],M2[p2][x]);
	if(M1[p1].count(x-1)&&M2[p3].count(x)) G[M1[p1][x-1]].push_back(M2[p3][x]),DEBUG(M1[p1][x-1],M2[p3][x]);
	if(M2[p1].count(x+1)&&M1[p2].count(x)) G[M2[p1][x+1]].push_back(M1[p2][x]),DEBUG(M2[p1][x+1],M1[p2][x]);
	if(M2[p1].count(x+1)&&M1[p3].count(x)) G[M2[p1][x+1]].push_back(M1[p3][x]),DEBUG(M2[p1][x+1],M1[p3][x]);
}
stack<int>S;
int SCC,dfn[5000005],low[5000005],Times,bel[5000005];
void Tarjan(int u)
{
	S.push(u);
	dfn[u]=low[u]=++Times;
	for(int i=0;i<(int)G[u].size();i++)
	{
		int v=G[u][i];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(!bel[v]) low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u])
	{
		int t=-1;SCC++;
		while(t!=u)
		{
			t=S.top();S.pop();
			bel[t]=SCC;
		}
	}
}
int main() {
//	freopen("data26.in","r",stdin);
	Ty1[1]='<'; Ty2[1]='>'; Ty2[2]='=';
	int n,m;read(n);read(m);
	for(int i=1,p1,p2,p3,x;i<=m;i++)
	{
		read(p1);read(p2);read(p3);read(x);
		P[i]=node(p1,p2,p3,x);
		brr[i]=x;
	}
	int tot=m;brr[++tot]=1;
	sort(brr+1,brr+1+tot); 
	tot=unique(brr+1,brr+1+tot)-brr-1;
	for(int i=1;i<=n;i++) M2[i][1]=++cnt,To[cnt]=mp(mp(i,1),2);
	for(int i=1;i<=m;i++)
	{
		int p1=P[i].p1,p2=P[i].p2,p3=P[i].p3,x=P[i].x;
		Init(p1,x); Init(p2,x); Init(p3,x);
		Connect(p1,p2,p3,x); Connect(p2,p1,p3,x); Connect(p3,p1,p2,x);
	}
	for(int i=1;i<=n;i++)
	{
		auto it=M1[i].begin(); 
		if(!M1[i].empty())
		{
			it++;
			for(;it!=M1[i].end();it++) G[(*prev(it)).second].push_back((*it).second),DEBUG((*prev(it)).second,(*it).second);	
		}
		it=M2[i].begin(); it++;
		for(;it!=M2[i].end();it++) G[(*it).second].push_back((*prev(it)).second),DEBUG((*it).second,(*prev(it)).second);
	}
	
	for(int i=1;i<=cnt;i++) if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=n;i++)
	{
		for(auto it=M1[i].begin();it!=M1[i].end();it++)
		{
			int Val=(*it).first+1,id=(*it).second;
			if(bel[id]==bel[M2[i][Val]]) return puts("NO")&0;
		}
	}
	puts("YES");
	for(int i=1;i<=n;i++)
	{
		for(auto it=M1[i].begin();it!=M1[i].end();it++)
		{
			int Val=(*it).first,x=(*it).second,y=M2[i][Val+1];
			if(bel[x]<bel[y]) {printf("%d ",Val);break;}
		}
		if(!M1[i].size()) printf("1 ");
	}
	return 0;
}
/*
瑶草一何碧,春入武陵溪。溪上桃花无数,花上有黄鹂。我欲穿花寻路,直入白云深处,浩气展虹霓。只恐花深里,红露湿人衣。
坐玉石,欹玉枕。拂金徽。谪仙何处,无人伴我白螺杯。我为灵芝仙草,不为朱唇丹脸,长啸亦何为。醉舞下山去,明月逐人归。
6 4
1 3 4 2
1 2 5 6
3 6 6 7
2 4 5 3

4 2
1 2 3 2
2 3 4 3
*/

「GYM 1004160」Meet in the Middle

题意

\(~~~~\) 给定两棵均有 \(n-1\) 个点的带权树,\(q\) 次询问,一个人从第一棵树的 \(a\) 出发,另一个从第二棵树的 \(b\) 出发。求 \(\max_{i=1}^n dis_1(a,i)+dis_2(b,i)\)
\(~~~~\) \(1\leq n\leq 10^5,1\leq q\leq 5\times 10^5\).

题解

\(~~~~\) 题目挺好的,部分分出得挺烂的,哦,不对,是根本没有。

\(~~~~\) 考虑如果所有询问的 \(b\) 固定,那我们有一种做法是在第一棵树的每个对应结点 \(i\) 再挂上一个点 \(i'\),中间边权为 \(dis_2(b,i)\)。那么现在的问题就是询问从 \(a\) 出发能到达的最远距离,显然维护直径的两个端点直接算距离就好了。

\(~~~~\) 那么当 \(b\) 不固定了的时候呢?我们把询问离线下来,那当 \(b\) 移动的时候会有一部分对应区间 (新移动到结点子树) 上挂的点直径下降,其他部分上升,那用一个线段树维护dfs序上一个区间的点集直径的端点即可。

代码
查看代码
#include <bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define mp(a,b) make_pair(a,b)
using namespace std;
template<typename T>void read(T &x)
{
    T f=1;x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
    x*=f;
}
ll T,n,q;
struct ST{
	vector <PII> G[100005];
	ll f[20][400005],Siz[400005];
	ll dep[400005],dis[400005],In[400005],Out[400005],To[400005],dfn[400005],Times;
	void dfs1(ll u,ll fa)
	{
		dep[u]=dep[fa]+1; f[0][++Times]=u; To[u]=Times;
		for(ll i=0;i<(ll)G[u].size();i++)
		{
			ll v=G[u][i].first;
			if(v==fa) continue;
			dis[v]=dis[u]+G[u][i].second;
			dfs1(v,u);
			f[0][++Times]=u;
		}
	}
	void dfs2(ll u,ll fa)
	{
		dfn[u]=++Times; To[dfn[u]]=u; Siz[u]=1;
		for(ll i=0;i<(ll)G[u].size();i++)
		{
			ll v=G[u][i].first,w=G[u][i].second;
			if(v==fa) continue;
			dis[v]=dis[u]+w; dfs2(v,u); Siz[u]+=Siz[v];
		}
	}
	inline ll Min(ll a,ll b){return dep[a]<dep[b]?a:b;}
	
	void Init()
	{
		for(ll i=1;i<=18;i++)
			for(ll j=1;j+(1<<(i-1))<=Times;j++) f[i][j]=Min(f[i-1][j],f[i-1][j+(1<<(i-1))]);
	}
	inline ll LCA(ll x,ll y)
	{
		if(x==y) return x;
		ll l=To[x],r=To[y];
		if(l>r) swap(l,r);
		ll d=__lg(r-l+1);
		return Min(f[d][l],f[d][r-(1<<d)+1]);
	}
	ll Dis(ll x,ll y){return dis[x]+dis[y]-2*dis[LCA(x,y)];}
}ST1,ST2;
struct BIT{
	ll tr[100005];
	inline ll lowbit(ll x){return x&(-x);}
	inline void Add(ll x,ll Val){for(;x<=n;x+=lowbit(x)) tr[x]+=Val;}
	inline ll Query(ll x){ll ret=0;for(;x;x-=lowbit(x)) ret+=tr[x];return ret;}
	inline void Modify(ll l,ll r,ll Val){if(l>r) return;Add(l,Val),Add(r+1,-Val);}
}BIT;
struct node{
	ll u,v,w;
	node(){u=v=w=0;}
	node(ll U,ll V,ll W){u=U;v=V;w=W;}
};
struct SegmentTree{
	#define ls p<<1
	#define rs p<<1|1
	#define lson p<<1,l,mid
	#define rson p<<1|1,mid+1,r
	node tr[400005];
	ll Tag[400005];
	node Merge(node a,node b)
	{
		ll c1=BIT.Query(ST2.dfn[a.u]),c2=BIT.Query(ST2.dfn[a.v]);
		ll c3=BIT.Query(ST2.dfn[b.u]),c4=BIT.Query(ST2.dfn[b.v]);
		ll u1=a.u,v1=a.v,w1=a.w;
		ll u2=b.u,v2=b.v,w2=b.w;
		ll u3=a.u,v3=b.v,w3=ST1.Dis(u3,v3)+c1+c4;
		ll u4=a.u,v4=b.u,w4=ST1.Dis(u4,v4)+c1+c3;
		ll u5=a.v,v5=b.u,w5=ST1.Dis(u5,v5)+c2+c3;
		ll u6=a.v,v6=b.v,w6=ST1.Dis(u6,v6)+c2+c4;
		ll Max=max(w1,max(w2,max(w3,max(w4,max(w5,w6)))));
		if(Max==w1) return node(u1,v1,w1);
		else if(Max==w2) return node(u2,v2,w2);
		else if(Max==w3) return node(u3,v3,w3);
		else if(Max==w4) return node(u4,v4,w4);
		else if(Max==w5) return node(u5,v5,w5);
		else return node(u6,v6,w6);
	}
	inline void pushUp(ll p){tr[p]=Merge(tr[ls],tr[rs]);}
	void Build(ll p,ll l,ll r)
	{
		if(l==r)
		{
			tr[p]=node(ST2.To[l],ST2.To[l],ST2.dis[ST2.To[l]]*2);
			return;
		}
		ll mid=(l+r)>>1;
		Build(lson); Build(rson);
		pushUp(p);
	}
	void pushTag(ll p,ll Val){tr[p].w+=2*Val; Tag[p]+=Val;}
	void pushDown(ll p){if(Tag[p]) pushTag(ls,Tag[p]),pushTag(rs,Tag[p]),Tag[p]=0;}
	void Modify(ll p,ll l,ll r,ll lx,ll rx,ll Val)
	{
		if(lx>rx) return;
		if(lx<=l&&r<=rx) return pushTag(p,Val);
		ll mid=(l+r)>>1; pushDown(p);
		if(lx<=mid) Modify(lson,lx,rx,Val);
		if(mid<rx)  Modify(rson,lx,rx,Val);
		pushUp(p);
	}
	#undef ls
	#undef rs
	#undef lson
	#undef rson 
}Seg;
ll Ans[500005];
vector <PII> Ask[100005];
void dfs3(ll u,ll fa)
{
	ll U=Seg.tr[1].u,V=Seg.tr[1].v;
	for(ll i=0;i<(ll)Ask[u].size();i++)
	{
		ll v=Ask[u][i].first,id=Ask[u][i].second;
		Ans[id]=max(ST1.Dis(U,v)+BIT.Query(ST2.dfn[U]),ST1.Dis(V,v)+BIT.Query(ST2.dfn[V]));
	}
	for(ll i=0;i<(ll)ST2.G[u].size();i++)
	{
		ll v=ST2.G[u][i].first,w=ST2.G[u][i].second;
		if(v==fa) continue;
		ll l=ST2.dfn[v],r=ST2.dfn[v]+ST2.Siz[v]-1;
		BIT.Modify(l,r,-w); BIT.Modify(1,l-1,w); BIT.Modify(r+1,n,w);
		Seg.Modify(1,1,n,l,r,-w); Seg.Modify(1,1,n,1,l-1,w); Seg.Modify(1,1,n,r+1,n,w);
		dfs3(v,u);
		BIT.Modify(l,r,w); BIT.Modify(1,l-1,-w); BIT.Modify(r+1,n,-w);
		Seg.Modify(1,1,n,l,r,w); Seg.Modify(1,1,n,1,l-1,-w); Seg.Modify(1,1,n,r+1,n,-w);
	}
}
int main() {
	read(T);
	read(n);read(q);
	for(ll i=1,u,v,w;i<n;i++)
	{
		read(u); read(v); read(w);
		ST1.G[u].push_back(mp(v,w));
		ST1.G[v].push_back(mp(u,w));
	}
	ST1.dfs1(1,0); ST1.Init();
	for(ll i=1,u,v,w;i<n;i++)
	{
		read(u); read(v); read(w);
		ST2.G[u].push_back(mp(v,w));
		ST2.G[v].push_back(mp(u,w));
	}
	ST2.dfs2(1,0);
	for(ll i=1;i<=n;i++) BIT.Modify(ST2.dfn[i],ST2.dfn[i],ST2.dis[i]);
	Seg.Build(1,1,n);
	for(ll i=1,a,b;i<=q;i++)
	{
		read(a);read(b);
		Ask[b].push_back(mp(a,i));
	}
	dfs3(1,0);
	for(ll i=1;i<=q;i++) printf("%lld\n",Ans[i]);
	return 0;
}
/*
瑶草一何碧,春入武陵溪。溪上桃花无数,花上有黄鹂。我欲穿花寻路,直入白云深处,浩气展虹霓。只恐花深里,红露湿人衣。
坐玉石,欹玉枕。拂金徽。谪仙何处,无人伴我白螺杯。我为灵芝仙草,不为朱唇丹脸,长啸亦何为。醉舞下山去,明月逐人归。
*/

举办乘凉州喵,举办乘凉州谢谢喵

举办出题人,举办出题人谢谢喵。

posted @ 2023-03-23 22:59  Azazеl  阅读(181)  评论(0编辑  收藏  举报