首页 > 其他分享 >Atcoder ABC 216 G 01Sequence 题解 [ 蓝 ] [ 差分约束 ]

Atcoder ABC 216 G 01Sequence 题解 [ 蓝 ] [ 差分约束 ]

时间:2024-11-14 23:30:20浏览次数:1  
标签:216 Atcoder le int 题解 ge 差分 约束 dijkstra

01Sequence:比较板的差分约束,但有一个很妙的转化。

朴素差分约束

设 \(x_i\) 表示第 \(i\) 位的前缀和。

我们要最小化 \(1\) 的个数,就要求最小解,就要求最长路。因为约束条件都是大于等于号,所以求最长路才能满足所有条件。求最大解也是同理。

我们可以对于每一个条件,列出如下不等式:

\[x_b \ge x_{a-1}+c \]

\[x_{i} \ge x_{i+1}-1 \]

\[x_{i+1} \ge x_i+0 \]

显然我们跑一遍 spfa 最长路即可求解。

时间复杂度最劣 \(O(n^2)\),容易被卡。

优化差分约束

我们考虑正难则反,把制约必须使用 spfa 的负权边化为正权边,就能跑 dijkstra 了。

设 \(x_i\) 表示第 \(i\) 位的 \(0\) 的个数的前缀和。

于是我们要求最大解,也就是最短路。

不等式如下:

\[x_b \le x_{a-1}+(b-a+1)-c \]

\[x_{i+1} \le x_{i}+1 \]

\[x_i \le x_{i+1}+0 \]

这样就可以跑 dijkstra 了。

时间复杂度 \(O(n \log n)\)。

用 dijkstra 或者缩点拓扑来优化差分约束的 spfa 是很常用的优化,一定要掌握。因为他们的本质都是求最短路或最长路,差分约束只是一种思想而已。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
int n,m,d[200005];
bitset<200005>vis;
vector<pi>g[200005];
priority_queue<pi,vector<pi>,greater<pi> >q;
void dijkstra(int s)
{
    memset(d,0x3f,sizeof(d));
    vis.reset();
    q.push({0,s});
    d[s]=0;
    while(!q.empty())
    {
        auto y=q.top();
        q.pop();
        int u=y.se;
        if(vis[u])continue;
        vis[u]=1;
        for(auto ed:g[u])
        {
            int v=ed.fi,w=ed.se;
            if(d[v]>d[u]+w)
            {
                d[v]=d[u]+w;
                q.push({d[v],v});
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        g[a-1].push_back({b,b-a+1-c});
    }
    for(int i=0;i<n;i++)
    {
        g[i+1].push_back({i,0});
        g[i].push_back({i+1,1});
    }
    dijkstra(0);
    for(int i=1;i<=n;i++)cout<<(1-(d[i]-d[i-1]))<<" ";
    return 0;
}

这题还可以上线段树贪心,也是比较容易的做法。

标签:216,Atcoder,le,int,题解,ge,差分,约束,dijkstra
From: https://www.cnblogs.com/zhr0102/p/18547159

相关文章

  • 2024年09月CCF-GESP编程能力等级认证Python编程二级真题解析
    本文收录于专栏《Python等级认证CCF-GESP真题解析》,专栏总目录:点这里,订阅后可阅读专栏内所有文章。一、单选题(每题2分,共30分)第1题据有关资料,山东大学于1972年研制成功DJL-1计算机,并于1973年投入运行,其综合性能居当时全国第三位。DJL-1计算机运算控制部分所使用的......
  • [CF1188E] Problem from Red Panda 题解
    [CF1188E]ProblemfromRedPanda题解考虑每个位置的操作次数\(c_i\),不难发现,\(i\)气球最后的颜色个数\(d_i\)是\(a_i+c_ik-\sumc_i\),如果存在\(\forallc_i>0\),那么我们总是可以把所有气球少操作一次,这样上式不变,不影响最后的序列,下文所有的操作序列都假设\(\min......
  • [JXOI2017] 加法 题解
    [JXOI2017]加法最小值最大,一眼二分。贪心地,每次尽量对包含当前序列最小值的区间做加法操作,也就是说,对于当前二分的答案\(x\),任何的\(A_i<x\)都需要被操作。从左到右地考虑答案。我们认为当前点之前的所有值都已经满足条件,于是我们只需考虑每次区间对当前点之后答案造成的贡......
  • 题解:P7836 「Wdoi-3」夜雀 collecting
    题解摘自做题记录。分析数据范围明显得要让我们分开搞。【Sub2】应该是暴力。这里有个主体思路,我们完全可以贪心地将当前背包里的食材删掉,直到每种出现过的食材数量刚好为\(1\)。因为我们保留更多的是没有用的。那么我们就可以用二进制数表示\(x\)种食材的出现状态了。同......
  • 【题解】CF1982
    A考虑两队的领先情况改变,那么一定有某一时刻两队的比分相等于是首先检查最开始的领先队伍,再检查现在的领先队伍,如果前后不同,则\(YES\),否则\(NO\)B注意到当\(x=1\),则会进入循环,手模一下发现\(ans=k\%(y-1)+1)\)现在的问题是:什么时候\(x=1\)?直接手动模拟即可,不难证明时......
  • Intellij IDEA如何设置中文版?安装中文汉化包插件?失败问题解决!
    前言大家好,我是小徐啊。IntellijIDEA默认是英文的操作界面,因为是外国人开发的嘛~对于英文好一点的同学来说,英文就英文吧,但对于英文比较差的同学,就还是希望能够汉化一下,变成熟悉的中文。今天小徐就来介绍下如何在IDEA中安装汉化插件,以及在这过程中,我遇到的奇怪问题,以及最后如何......
  • P8099 [USACO22JAN] Minimizing Haybales P 题解
    好题图论的难点在于建图~首先我们关注到如果两个草堆之间的差大于K,那么他们的位置就是固定的,就相当于给了一些限制,这就是很经典的连边然后拓扑排序。其实你是不是可以直接从小的向大的连边(我没试)然后再做排序。这一部分代码(粗略验证正确性,赶着写的,可能比较一言难尽)#include<bi......
  • Atcoder Beginner Contest 379 (A-F)
    AtcoderBeginnerContest379(A-F)题目链接A-Cyclic#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;voidShowball(){chara,b,c;cin>>a>>b>>c;cout<<b<<c<<a<<""<......
  • 【考试题解】NOIP2024(欢乐)加赛3
    目录A.SakurakoandWater题目内容思路代码B.BinomialCoefficients,KindOf题目内容思路代码C.QED'sFavoritePermutation题目内容思路代码D.CardGame题目内容思路代码E.LongWaytobeNon-decreasing题目内容思路代码F.ManyGames题目内容思路代码A.SakurakoandW......
  • COCI19-20#6 Trener题解
    COCI19-20#6Trenerlink一道水题(我真是太弱了啊啊啊啊。众所周知,看到这个题立刻知道他是要选名字长度为$1$到$N$的,而我们知道他每一个名字,所以可以直接用字符哈希去做,因为他每一个名字的字符数是上一层名字的字符数加一,所以对于哈希每个字符串只需要跑三次,分别是自己的这......