洛谷11月月赛 Dev.2 简要题解

本文深入解析了算法竞赛中的几个关键问题,包括最短路径、序列分析、加权贡献和资源分配策略。通过巧妙的数学转换和贪心算法,文章提供了解决这些问题的有效方法,如生成树、动态规划和线段树等高级数据结构的应用。

T2
题意:
给定 nnn个点mmm条边的无向简单联通图GGG,边有边权,保证没有重边和自环
定义一条简单路径的权值为路径上所有边边权的异或和
保证GGG中不存在简单环使得边权异或和不为 000
QQQ次询问xxxyyy的最短简单路径

善于利用题目条件的你发现一个环走哪一边都是可以的,于是按输入顺序求出任意一棵生成树即可


T3:
题意:一个序列 BBB,从第一个位置开始,每次可以跳到一个 j∈[i,i+m],bj>0j\in [i,i+m],b_j>0j[i,i+m]bj>0jjj,走不动的为输,问先手必胜?BBBAAA 中的 [l,r][l,r][l,r]n≤1e6,q≤1e7n\le 1e6,q\le 1e7n1e6,q1e7

暴力从后向前解 sgsgsg 函数
考虑一个点 iii,如果向后 m [i+1,i+m][i+1,i+m][i+1,i+m]sgsgsg 存在一个 0 即必败情况,那么当前必胜
如果全部是 1 且当前是奇数,那么你死定了,sgsgsg 为 0,否则 sgsgsg 为 1

我们巧妙的发现如果是偶数那么一定为 1,而如果 iii 是 0,那么下一个出现 0 的位置至少在[i−m−1,i][i-m-1,i][im1,i] 之后并且一个点 iii 向前到的那个节点是一定的
先处理出连续一段偶数的最前面的那个点,然后一个处理一个点向前面跳到的那个点,倍增优化,跳到刚好在lll 之前的那个点判断其是否为 lll 即可,O((n+q)log(n))O((n+q)log(n))O((n+q)log(n))

发现最后可以连成一棵树,问题转化为对每个点求它到根的路径上存不存在一类点
dfsdfsdfs 保留一条链的信息退栈的时候删除即可


T4:
题意:给一个 {a1,a2,...,an},{w1,w2,...,wn}\{a_1,a_2,...,a_n\},\{w_1,w_2,...,w_n\}{a1,a2,...,an},{w1,w2,...,wn}
一个 xxx 初始为 0,每次可以给一个 xxx 加上 j∈[−k,k]j\in[-k,k]j[k,k]
记第 iii 次的结果是 bib_ibi,要求 bi≤aib_i\le a_ibiai,最大化 ∑ibiwi\sum_i b_iw_iibiwi
n≤1e6n\le 1e6n1e6

首先发现加上一个负的很烦,可以考虑每次操作将当前全部减 kkk,然后在 [0,2k][0,2k][0,2k] 讨论

有一个比较巧妙的转换,就是将每一次加的操作的贡献独立开来
其实就是一个比较常见的拆贡献的套路,记第 iii 次加的数是 ci∈[0,2k]c_i\in[0,2k]ci[0,2k]
max(∑biwi)=max(∑i=1nwi∗∑j=1icj)=∑j=1ncj∑i=jnwimax(\sum b_iw_i)=max(\sum_{i=1}^nw_i*\sum_{j=1}^ic_j)=\sum_{j=1}^nc_j\sum_{i=j}^nw_imax(biwi)=max(i=1nwij=1icj)=j=1ncji=jnwi
www 的后缀和是 sss,就是最大化 ∑cisi\sum c_is_icisi 同时满足∀i,∑j≤icj≤ai+i∗k\forall i,\sum_{j\le i}c_j\le a_i+i*ki,jicjai+ik
后面的可以一开始就是加上

显然先取 sis_isi 更大的最优,直接贪心,按 sis_isi 从大到小排序
考虑 aia_iai 的限制,每次能取到的就是后缀的一个最小值,把它砍成 000,并且之后的讨论只能在这个位置之后,可以线段树维护最小值以及区间加,也可以记一个全局减的 tagtagtag 一开始求一个后缀 minminmin 就可以了,复杂度 O(n)O(n)O(n)

洛谷p5736 【深基7.2】质数筛是一个关于质数筛法的题目,要我们根据输入的一个正整数n,找出小于等于n的所有质数。 质数是指只能被1和自身整除的大于1的整数,比如2、3、5、7等。质数筛法是一种常见且高效的找出质数的方法。 在这道题中,我们需要使用质数筛法来找出小于等于n的所有质数。首先,我们定义一个boolean类型的数组isPrime,用来标记每个数字是否是质数。初始时,我们将isPrime数组的所有元素都设置为true。 然后,我们从2开始遍历到n,对于每个数字i,如果isPrime[i]为true,说明这个数字是质数。那么我们就需要将i的倍数都标记为false,因为这些倍数一定不是质数。具体做法是,从2*i开始,每次增加i,将对应的isPrime数组的元素都置为false。 遍历结束后,isPrime数组中为true的元素即为小于等于n的所有质数。我们可以遍历isPrime数组,将为true的下标即为质数输出即可。 这个算法的时间复杂度是O(nloglogn),相较于直接遍历每个数字并判断是否是质数的方法,时间复杂度更低,效率更高。 对于这个题目的java实现,我们可以使用一个boolean数组isPrime来标记每个数字是否是质数,使用一个ArrayList来存储所有的质数,最后将ArrayList转化为数组输出。 代码示例如下: ``` import java.util.ArrayList; public class Main{ public static void main(String[] args){ int n = 100; // 输入的正整数n boolean[] isPrime = new boolean[n+1]; // 标记每个数字是否是质数的数组 ArrayList<Integer> primes = new ArrayList<>(); // 存储质数的ArrayList // 初始化isPrime数组 for(int i=2; i<=n; i++){ isPrime[i] = true; } // 质数筛法 for(int i=2; i<=n; i++){ if(isPrime[i]){ primes.add(i); for(int j=2*i; j<=n; j+=i){ isPrime[j] = false; } } } // 将ArrayList转化为数组输出 int[] result = new int[primes.size()]; for(int i=0; i<primes.size(); i++){ result[i] = primes.get(i); } // 输出结果 for(int i=0; i<result.length; i++){ System.out.print(result[i] + " "); } } } ``` 这样,我们就可以通过这段代码来实现洛谷p5736题目的要,找出小于等于输入的正整数n的所有质数,并将它们按从小到大的顺序输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值