ACM题解吖

H:(实为NOIP2014T3)

其实左边的式子是可以用秦九韶算法解决的

但是难就难在如果你硬乘,就要写高精度,所以为了防爆int,我们可以mod一个素数把范围缩小

首先要知道的是高次方程无求根公式,所以解这个方程没有公式,套公式只能过30%的数据

一种方法是枚举1到m的正整数,判断行不行。

若用高精度则只能能拿50分,那如何优化呢?取模!

设f(x)=a0+a1*x+a2*x^2+..+an*x^n

若f(x)=0则f(x) mod p=0(p为任意非0实数)

但有几点要注意:

1。p最好是质数 2。p试得越多,p越大正确率越高,但也会慢一点点,根据实际情况自己调节

随意试几个p,若f(x) mod p都是0,那x很有可能就是方程的解

秦九韶算法我默认你们都会的,毕竟连读入优化都要用到这个

 硬枚举素数绝对要爆,所以有了个优化:

注意到如果 一个100000以内的数x不符合要求,那么 x+99991,x+99991×2x+99991 imes2x+99991×2....都不会满足要求。

因此我们只要找到了一组1-99991以内的解就只需判断 x+99991,x+99991×2x+99991 imes2x+99991×2....即可。

K(带领我再再再次学会了带权并查集) luogu P5092

点权并查集与边权是不一样,因为维护的更多

对于字符:cin的输入忽略空格和回车。

w[]即我们要维护的权值,即石头的高度嘛,对于合并一定是模拟,去发现要怎样去更新,要维护哪些额外的东西。

fy,fx要找准到底对于这道题是什么,毕竟会初始化,所以还好可以找到

C(一种二分,一种卡时,一种堆)

method one:卡时

告诉了我们int 2e9

  • 事实上,只要在朴素算法的代码上加一个小优化就行了。
  • 两个长度为N的数列,和的总数为N^2,而答案只要输出其中最小的N个即可,那容易想到,在往堆中插入时就排除掉一些绝对不可能是答案的数。
  • 假设此时要把 a[i]+b[j]a[i]+b[j]a[i]+b[j] 插入堆,且(i−1)∗(j−1)>N(i-1)*(j-1)>N(i1)(j1)>N,那么这个数一定不会是最后的答案,因为对于1<=s<i,1<=t<j1<=s<i,1<=t<j1<=s<i,1<=t<j,可组成的和已经超过N个,且都要比a[i]+b[j]a[i]+b[j]a[i]+b[j]小

method two:

F(找区间众数)

保证出现次数超过n/2

那么我们每得到一个数,就与之前保存的数(即当前出现次数最多且未被抵消的数)比较,如果与之前的不同,tot--,相当于是抵消了一个。如果发现tot=0,那么说明之前的数字耗尽了,那么我们把新的读进来的数作为新的保存的数就可以了。

神奇的地方就在于这个抵消操作。最后得到的数字一定会是众数。

注意:

内存1MB,头文件不能开多,以后记住最好不要用万能头文件

所有程序return 0

I(road)

拓扑排序

 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

(by 百度百科)

 照个人理解,拓扑排序通常是在DAG图中寻找一个适合的解决问题的顺序。

如何实现拓扑排序

方法1:BFS(SPFA优化)

1、先寻找入度为0的点,把它加入队列。

2、搜寻队列,把队列的点G删去,则如果有点的入度有G点的话,入度- -,当发现又出现入度为0的点时,将该点加入队列。

3、拓扑排序的结果为该队列,在执行删点操作的时候存储在一个数组及可。

方法2:记忆化搜索

大多数情况下,并不需要显式的拓扑排序

考虑朴素的回溯算法

若从一个给定的点出发,得到的结果是一样的

因此对于每个点,计算完成后可以把结果保存起来,之后直接返回查表的结果即可

拓扑排序伪代码(1):

Topological_sort(G){
    统计图G中每个点的入度(可计算重边,但不可计算自环),记为degree[i]
    初始化queue和result为空的队列,并将所有degree为0的点加入queue
    while (!queue.empty()){
        u = queue.pop() // 队首
        result.push(u)
        for e 是u的出边(若上面计算了重边,这里也要算,与上面一致)
        v是e的指向的点
        degree[v]--
        if (degree[v] == 0) queue.push(v)
    }
    return result
}

拓扑排序伪代码(2):

calculate(u){
    if (u 已经搜索过) return table[u]
    ans = -inf
    for (v 是u的出边指向的点)
    ans = max(ans, value[u] + calculate(v))
    标记u已经搜索过
    table[u] = ans
    return ans
}
for (i 是G的所有节点)
result = max(result, calculate(i))
print(result)

本题思路:有向无环图,根据topo序去dp

拓扑排序就可以求dp顺序(如果有DAGdp的话,建议加个拓扑)

(对于这道题的dp,拓扑无意义,所以可以跳过拓扑,直接dp)

哇,我为什么记不到dp初始化,damn it

G(看似是博弈论,实为搜索)

 
原文地址:https://www.cnblogs.com/lkx422/p/11220541.html