Gravatar
┭┮﹏┭┮
积分:4451
提交:907 / 1937

首先可以不是简单路径,这启示我们用并查集,但 $a,b$ 的二维限制有些不可做,我们可以先想暴力,对于每个询问只需将所有 $a_i \leq a$ 且 $b_i \leq b$ 的所有边加入并查集,并维护最大 $a,b$ 值,判断 $u,v$ 是否在一个联通块内,且最大值即为 $a,b$,这样可以 $\mathcal{O}(mq\log{n})$。


限制太特殊了,我们考虑分块,首先将所有边按照 $a$ 排序后分块,每个询问离线下来后把其放到尽量右块内,使所有其左边的块的 $a$ 值都小于等于它,然后我们枚举每个块,将该块询问先按照 $b$ 排序,再将前面的块按照 $b$ 排序,双指针加边即可。


对于在该块内的边,我们暴力枚举加边,枚举后撤销这些操作,所以 并查集不能路径压缩,只能按秩合并。


复杂度 $\mathcal{O}(qB\log{n} + \frac {m^2} B \log{n})$,取 $B = \sqrt{m}$ 得复杂度为 $\mathcal{O}((q + m)\sqrt{m}\log{n})$。


但是貌似 $B = \sqrt{m\log{n}}$ 跑的最快 : )。



题目2241  [HNOI 2016] 最小公倍数      6      评论
2024-09-10 12:43:49    
Gravatar
┭┮﹏┭┮
积分:4451
提交:907 / 1937

首先我们假设两条边 $(u1,v1)$,$(u2,v2)$ 中间未选择断边,则我们可以考虑 DP,设 $f_i$ 表示 必须选 $(fa_i,i)$ 这条边时在其子树内走可以得到的最大贡献,则任意一点 $v$ 在其子树内,则有转移方程 $f_i = \max\limits_{v \in son(i)} f_v + size_v \times (size_u - size_v)$,这东西可以用 李炒熟 维护,对于树形结构可以用 李超树合并 解决子树问题。


但是这显然没完,上述所求的只是在一条链 从子树到祖先 上的路径,然后我们考虑在某个点合并两条链,假设合并两点 $u,v$,则需要再减去重复的贡献 $size_u \times size_v$,所以我们求得答案即为 $f_u + f_v - size_u \times size_v$ 的最大值,显然也可以用 李焯书,然后考虑如何合并,显然可以用 淀粉质,复杂度是 $\mathcal{O}(n\log^2{n})$ 的,但巨大长代码。


知周所众,dsu on tree 是可以代替一些淀粉质的,所以我们考虑用 dsu on tree,考虑每个点 $x$,保存其 重儿子 的李超树,其余节点暴力查询答案,然后进行 李焯书贺兵 即可,复杂度也是 $\mathcal{O}(n\log^2{n})$,但较好写,常数也小。



题目3922  删除题目 AAAAAAAAAAAAAAAAAAAA      7      评论
2024-09-05 22:00:36    
Gravatar
┭┮﹏┭┮
积分:4451
提交:907 / 1937

首先我们考虑如何求每个点的贡献,可以发现只有最后一次经过某点的时间是有用的,我们可以考虑 最少失去的法力值,设其为 $w$ ,则答案即为 $s \times \sum m - w$,$n$ 较小,考虑状压 DP,因为询问规定了最终点,所以一维是不行的,设 $f_{i,j}$ 表示已经最后一次经过状态 $i$ 中的点,且当前在 $j$ 位置的最小答案,则有状态转移方程:

$$f_{i,j} = \min {f_{la,k} + d_{k,j} \times s_{la}}$$


其中 $d_{i,j}$ 表示 $i$ 到 $j$ 的最短路,$s_{i}$ 表示状态 $i$ 中所有节点的 $m$ 和。


然后对于答案,即为 $ans = \underline{s_{i}}_k \times \underline{s}_x + (\underline{-f_{i,j}}_b)$,显然可以 李焯书 解决。


复杂度 $\mathcal{O}(2^nn^2 + 2^nn\log{V} + q\log{V})$,当然也可以维护凸包,但是瓶颈不在这,复杂度差不多。



Gravatar
kdb
积分:20
提交:20 / 75
×

提示!

该题解未通过审核,建议分享者本着启发他人,照亮自己的初衷以图文并茂形式完善之,请勿粘贴代码。

#include<bits/stdc++.h>

using namespace std;

int main()

{ <

........................................................................

该题解等待再次审核

........................................................................(剩余 537 个中英字符)

题目3927  [CSP 2023J]小苹果
2024-07-23 08:29:25    
Gravatar
王艺博喜欢厉琪冉
积分:8
提交:10 / 51
×

提示!

该题解未通过审核,建议分享者本着启发他人,照亮自己的初衷以图文并茂形式完善之,请勿粘贴代码。

#include<bits/stdc++.h>

using names

........................................................................

该题解等待再次审核

........................................................................(剩余 292 个中英字符)

题目984  [NOIP 2010PJ]数字统计
2024-07-20 08:32:15    
Gravatar
AeeE5x
积分:478
提交:115 / 283

先说结论:

本题泛用性强,对策性一般,属于中杯偏下难度

(?)


P个点(不是N,别弄错了)),C条边,把奶牛当成点的权值,求所有点到一个点的最短距离与权值的乘积和

很标准的带权最短路问题,像是Dijkstra(需要堆优化)、Floyd(无向图优化)、SPFA什么的都可以)


因为不会Dijkstra的堆优化和SPFA遂写了Floyd(但是特别慢)(O((P^3)/2))


#include<iostream>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
int n,p,m;
int pt1[810]; //奶牛所在节点 
int gra[810][810]; //邻接矩阵 
void f(){
	for(int k=1;k<=p;k++){
		for(int i=1;i<=p;i++){
			for(int j=1;j<i;j++){ //无向图,A到B和B到A一样,可以只算一半 
				if(gra[i][j]>gra[i][k]+gra[k][j]){
					gra[i][j]=gra[i][k]+gra[k][j];
					gra[j][i]=gra[i][j];
				}
			}
		}
	}	
}	
int main(){
	freopen("butter.in","r",stdin);
	freopen("butter.out","w",stdout);
	
	memset(gra,0x3f,sizeof gra); //初始化 
	
	scanf("%d%d%d",&n,&p,&m);
	for(int i=1;i<=n;i++){
		int k;scanf("%d",&k);
		pt1[k]++; //奶牛节点 
	}
	
	for(int i=1;i<=m;i++){
		int a,b,k;scanf("%d%d%d",&a,&b,&k);
		gra[a][b]=gra[b][a]=k;
	}
	
	for(int i=1;i<=p;i++) gra[i][i]=0; //到自身距离为0 
	f(); //Floyd 
	
	int ans=0x3f3f3f3f;
	for(int i=1;i<=p;i++){
		int sum=0;
		for(int j=1;j<=p;j++) sum+=gra[j][i]*pt1[j]; //用距离乘这个节点的奶牛数量,就是这个节点奶牛走的总距离 
		ans=min(ans,sum);
	}
	printf("%d",ans);
	
	return 0;
}

2024.7.19更新:

洛谷上一组数据卡了我半天 原因是:这个图不联通

所以应该在算ans的地方加个特判,这样才能过洛谷的数据)

if(gra[j][i]==0x3f3f3f3f&&pt1[j]) break;

小杯理解 逃逸了)




题目309  [USACO 3.2] 香甜的黄油      6      1 条 评论
2024-07-19 15:57:01