[题解向] 正睿Round409

\(\rm Link\)

然而泥萌没有权限是看不了题目的233.

\(\rm T1\)

大概就是个map,脑残出题人认为(x,x)不属于有序二元组,我可qtmd。于是只拿了\(\rm 60pts\)

int main(){
    ios_base :: sync_with_stdio(false) ;
    cin.tie(0), cout.tie(0) ; cin >> N >> P ; int i ;
    for (i = 1 ; i <= N ; ++ i) cin >> base[i], base[i] %= P ;
    for (i = 1 ; i <= N ; ++ i) if (base[i]) M[expow(4 * base[i] % P, P - 2)] ++ ;
    for (i = 1 ; i <= N ; ++ i){
        int now = 1ll * base[i] * base[i] % P ;
        ans += M[now] ; if (4ll * now % P * base[i] % P == 1) -- ans ;
    }
    cout << ans << endl ; return 0 ;
} 

\(\rm T2\)

先说自己的做法。

发现其实就是在凑一个式子:

\[\frac{\sum a_ik_i}{M\sum k_i}=\frac{N}{M}\]

然后稍微变个形:

\[\sum a_ik_i=N\cdot \sum k_i\]

于是发现只要暴力背包就完了,最后判断一下\(f_{k,N}\)是不是\(=k\)就做完了。

int main(){
    cin >> K >> N >> M ; int i, j ; dp[0] = 0 ;
    for (i = 1 ; i <= K ; ++ i) cin >> base[i] ;
    for (i = 1 ; i <= N * N ; ++ i) dp[i] = Inf ;
    for (i = 1 ; i <= K ; ++ i)
        for (j = base[i] ; j <= N * N ; ++ j)
            dp[j] = min(dp[j - base[i]] + 1, dp[j]) ;
    for (i = 1 ; i <= N ; ++ i) if (dp[i * N] == i) return cout << i, 0 ;
    return -1 ;
}

于是获得了\(\rm 70pts\)……但是用头想一想,发现并不对。因为可能\(f_{k,N}\)这个状态的\(\rm cost\)可能是5,但是背包转移的时候只能记录最优状态,于是假设会记录4,那这个状态就挂掉了……对每个状态都开了个std :: set发现T掉了……

正解是BFS。

考虑把式子转化一下,就变成了

\[\sum k_i(a_i-N)=0\]

大概就是考虑用已经凑出的和当做状态,那么实际上是在找一个环。于是每次转移的时候枚举放哪个新物品(新物品权值为\(a_i-N\))就完了。

#define MAX 50000
    cin >> K >> N >> M ; q.push(MAX) ; vis[MAX] = 1 ; int i ;
    for (i = 1 ; i <= K ; ++ i) cin >> base[i], base[i] -= N ;
    while (!q.empty()){
        int now = q.front() ; q.pop() ;
        if (now > M + MAX) continue ;
        for (i = 1 ; i <= K ; ++ i){
            if (now + base[i] == MAX){
                cout << ans[now] + 1 << endl ;
                return 0 ;
            }
            else if (!vis[now + base[i]])
                vis[now + base[i]] = 1, ans[now + base[i]] = ans[now] + 1, q.push(now + base[i]) ;
        }
    }
    cout << -1 << endl ; 

正 解 暴 力, 菜 鸡 退 役。

\(\rm T3\)

sb题,每个连通块都产生\(\rm 1\)的贡献当且仅当没有任何一个连通块是树。

于是就变成了找树的问题……忘记前驱思考了nm老久,趁早退役算了= =

void dfs(int now, int pre){
    vis[now] = 1 ;
    for (int k = head[now] ; k ; k = E[k].next){
        if (to(k) == pre) continue ;
        if (to(k) == now) continue ;
        if (!vis[to(k)]) dfs(to(k), now) ; else ++ o ;
    }
}
int main(){
    cin >> N ; int i ; p = 1 ;
    for (i = 1 ; i <= N ; ++ i) fa[i] = i ;
    for (i = 1 ; i <= N ; ++ i) cin >> base[i], add(i, base[i]) ;
    for (i = 1 ; i <= N ; ++ i) if (fa[i] == i) ++ ans ;// cout << ans << endl ;
    for (i = 1 ; i <= N ; ++ i) if (!vis[i]) o = 0, dfs(i, 0), p = min(o, p) ;
    if (p) cout << ans << endl ; else cout << ans - 1 << endl ; 

\(\rm T4\)

BZOJ4160.

不可做题233

题面:

给定一张无向图,求给这张图定向成\(\rm DAG\)之后最长路最短是多少。\(n\leq 16\)

\(\rm{Sol~1}\)

考虑直接\(dp\)。\(f_{s,u,v}\)表示考虑了点集\(s\),最长路端点是\(u,v\)的最小值。每次转移的时候枚举\(u,v,w\),从\((u,v),(v,w)\)两个状态转移到\((u,w)\)。复杂度\(O(3^nn^3)\)

1h没调出来

\(\rm Sol~2\)

考虑证明一个二级定理:

定理 \(1.1\)

  • 一张无向图定向成的\(\rm DAG\),当其最长路最短时,其最长路为\(\rm X-1\),其中\(\rm X\)表示不连通集覆盖数。也就是对于一张有向图图\(\rm \{V,E\}\),定义一种划分\(P\),使得划分出的每个集合中所有点不连通。

考虑一种证明:

  • 首先一定有\(\rm X-1\geq maxL\)。因为其上的每个点是连通的。
  • 其次我们考虑,如果每次删除全部出度为\(0\)点,放到一个集合里,那么一定合法,并且可以满足\(\rm X=maxL+1\)。

但其实这东西也可以直接用\(\rm dilworth\)定理的对偶定理证出来:

定理 \(2.1\)(\(\rm dilworth\)定理)

令\(\rm (X,≤)\)是一个有限偏序集,并令\(m\)是反链的最大的大小。则\(\rm X\)可以被划分成\(m\)个但不能再少的链。

对偶一下:

定理 \(2.2\):
令\(\rm (X,≤)\)是一个有限偏序集,并令\(r\)是其最大链的大小。则\(X\)可以被划分成\(r\)个但不能再少的反链。

然后”反链“连接的是”不可比的点“,也就是本题中”不连通的点“。

于是我们就可以快乐地状压了。

int *g, *f ;
int main(){
    cin >> N >> M ;
    memset(f, 63, sizeof(f)) ;
    int u, v, i, j ; T = (1 << N) - 1 ;
    for (i = 1 ; i <= M ; ++ i)
        cin >> u >> v, -- u, -- v, E[u] |= (1 << v), E[v] |= (1 << u) ;
    f[0] = 0, g[0] = 1 ;
    for (i = 0 ; i <= N ; ++ i) Sz[1 << i] = i ;
    for (i = 1 ; i <= T ; ++ i){
        j = (i & (-i)) ;
        if (!g[i ^ j]) continue ;
        if (E[Sz[j]] & (i ^ j)) continue ;
        g[i] = 1 ;
    }
    for (i = 1 ; i <= T ; ++ i)
        for (j = i ; j ; j = (j - 1) & i)
            if (g[j]) f[i] = min(f[i], f[i ^ j] + 1) ;
    cout << f[T] - 1 << endl ; return 0 ;
}

原文地址:https://www.cnblogs.com/pks-t/p/11748764.html

时间: 2024-08-11 11:52:22

[题解向] 正睿Round409的相关文章

[题解向] 正睿Round435

10.14 Link 唔,这一场打得不好.获得了\(\rm 75pts/300pts\)的得分,但是居然可以获得\(\rm 27/69\)的名次,也不至于不满意--毕竟是真不会233 \(\rm T1\) 大概就是字典序那个地方比较爆炸-- 于是就考虑奇数开头和偶数开头分开做,对于每种情况调整成一个合法最小代价序列.这个地方有一个贪心,原来在前面的依旧会在前面,在后面的也还会在后面,扫一遍就做完了. 这个贪心里面蕴含着一个性质.\(now_i<i,now_j<j\),即"同向换&qu

9.22 正睿提高4

目录 2018.9.22 正睿提高5 A 数组计数(DP) B 旅行(思路) C 进化(思路 二进制拆分) 考试代码 B C 2018.9.22 正睿提高5 时间:3.5h 期望得分:100+80+30 实际得分:100+80+30 比赛链接 T2一直以为类似某道虚树题(SDOI2015)..到最后只想写暴力(写了暴力也该想到了啊 但是已经在划水了). A 数组计数(DP) 题目链接 DP.前缀和优化一下就行了. 刚开始滚动数组又少清空了mmp.. #include <cstdio> #inc

正睿OI国庆DAY2:图论专题

正睿OI国庆DAY2:图论专题 dfs/例题 判断无向图之间是否存在至少三条点不相交的简单路径 一个想法是最大流(后来说可以做,但是是多项式时间做法 旁边GavinZheng神仙在谈最小生成树 陈主力说做法是dfs 首先两个点一定在点双联通分量里 点双是简单环,只有两条,不存在 猜测其他情况存在三条 双联通分量分解 输出情况可以用dfs树判,讨论非树边覆盖情况 内包含 下面分叉连到上面 相交 输出点即可 BFS/例题 BFS树没有跳跃边 计数/动态规划有用吧 树上bfs序好像可以判断距离? 边权

正睿OI DAY3 杂题选讲

正睿OI DAY3 杂题选讲 CodeChef MSTONES n个点,可以构造7条直线使得每个点都在直线上,找到一条直线使得上面的点最多 随机化算法,check到答案的概率为\(1/49\) \(n\leq k^2\) 暴力 \(n\geq k^2\),找点x,求直线l经过x,且点数最多,点数\(\geq k+1\),递归,否则再找一个 One Point Nine Nine 现在平面上有\(n\)个点,已知有一个常数\(D\). 任意两点的距离要么\(\leq D\),要么\(\geq 1.

正睿多校联盟训练Week6

并没有参加 Problem A.阿瓦分蛋糕输入文件: cake.in输出文件: cake.out时间限制: 1 second空间限制: 512 megabytes阿瓦为了庆祝自己自己成长为了一只可爱的小猫,决定提前过生日!她觉得,在这一年当中帮助过他最多的就是阿卡和烤乐滋了,于是决定这次只请阿卡和烤乐滋两个人吃蛋糕.阿瓦买了一个 n × m 的蛋糕,她打算分给三个人吃,同时她切蛋糕的时候为了美观,只会在整块的蛋糕上一划到底.也就是说,她如果在蛋糕上切了一刀,那么这一刀的起点和终点一定在蛋糕的边界

正睿提高组2017模拟题二T2

不会线性的,但是群里有个大神,发现用可以用80分的复杂度写出100分的效果,于是.... 考虑每次加入一条边,我们用f[x][j]表示加入第i条边后,当前的并查集x中,第j个点的父亲.那么如何加呢?假设当前第i条边的两端点为u和v,如果第x个并查集中u和v联通那么很明显,它不可以再加到这个并查集中(每个并查集维护的就是一个极大森林),然后就往后找,直到能找到一个x使得其中u和v是不连通的为止(肯定能找到,因为如果已有的都已经连通,说明前x个极大森林中都无法删去这条边,所以再构建一个新的并查集就好

正睿提高组2017模拟题三T1

听了很久又看了很久别人的程序才听懂,于是乎记录一下防止以后忘记. 好啦,假设当前 l-1=5,r=7;那如果学习过树状数组的话就知道题目中的操作如果转换为二进制的话 对于l-1来说他的二进制是101,所以会被加上-1的位置是101和100,r的二进制是111,所以会被加上1的位置是111,110,100 所以可以发现最后更新的位置是l-1的二进制的1的个数+r的二进制的1的个数-2*l-1和r都会更新的位置. 而l-1和r减1都会更新的位置的个数是它们两个二进制的最长公共前缀的1的个数(当然,前

正睿多校联盟训练Week5

T1 Problem A. 阿瓦的海报输入文件: poster.in输出文件: poster.out时间限制: 1 second空间限制: 512 megabytes阿瓦为了宣传她的影展,准备画一张海报张贴在幻想镇的各个角落.她为了让海报引人注目,已经在图案.背景和排版上费了很大的工夫.但这时她接到一个来自印刷厂的通知:印刷厂的纸不够了,本来答应给阿瓦定做的海报不能达到预期的尺寸.印刷厂表示,剩下的纸最多能够承担每张海报的面积为 S.而阿瓦认为,海报的面积应当是越大越好,所以阿瓦决定,就将每张海

9.1 正睿提高2

目录 2018.9.1 Test A(凸壳 单调栈) B(思路 独立) C 考试代码 A B C 2018.9.1 Test 时间:3.5h 实际得分:40+50+20 比赛链接 T1直接忽略了,刚了3小时T2(暴力写法不好,直接乘逆元就行→_→),算是有点成果吧.. 然后20分钟写完T1.T3.感觉T3也算可做的. A(凸壳 单调栈) 题目链接 注意到\(c_i=0\),即二次函数对称轴都为y轴,但是好像还是很难做.. 但是这样我们可以把一个x提出来,变成\(x(ax+b)\). 所以\(x>