AtCoder AGC030B Tree Burning

题目链接

https://atcoder.jp/contests/agc030/tasks/agc030_b

题解

细节好题。。
首先假设第一步往右走,那么可以发现当拐弯的次数一定时路径是唯一的
于是可以枚举这个值
然后很烦的是枚举之后要分奇偶讨论。。
最后再翻过来做一遍处理第一步往左走就行了
时间复杂度\(O(n)\)

代码

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define llong long long
using namespace std;

void read(int &x)
{
    int f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

const int N = 2e5;
llong a[N+3];
llong s[N+3];
int n; llong m,ans;

void solve()
{
    s[0] = 0ll; for(int i=1; i<=n; i++) s[i] = s[i-1]+a[i];
    for(int i=1; i<=n; i++)
    {
        llong tmp;
        if(i&1)
        {
            int x = (i-1)>>1;
            tmp = (m*x-(s[n]-s[n-x]))*2+a[n-x]+(s[n-x-1]-s[n-x-x-1])*2;
        }
        else
        {
            int x = i>>1;
            tmp = (m*(x-1)-(s[n]-s[n-x+1]))*2+(m-a[n-x+1])+(s[n-x]-s[n-x-x])*2;
        }
        ans = max(ans,tmp);
    }
}

int main()
{
    scanf("%lld%d",&m,&n);
    for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
    solve();
    for(int i=1; i<=n; i++) a[i] = m-a[i];
    reverse(a+1,a+n+1);
    solve();
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/suncongbo/p/11366473.html

时间: 2024-10-30 04:02:09

AtCoder AGC030B Tree Burning的相关文章

AGC 030 B - Tree Burning

B - Tree Burning 链接 题意: 一个长度为L的环,有n个位置上有树,从0出发,每次选择一个方向(顺时针或者逆时针),一直走,直到走到一棵树的位置,烧掉这棵树,重复这个过程,直到没有树.求最多走多少距离. 分析: 最优一定是LLLRLRLRL……类似这样的,于是枚举每个点,计算答案. 代码: 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<iostream

AGC 030B.Tree Burning(贪心)

题目链接 \(Description\) 有一个长为\(L\)的环,上面有\(n\)棵树,坐标分别为\(a_i\).初始时在原点. 每次你可以选择顺时针或逆时针走到第一棵没有被烧掉的树,停在这个位置,然后烧掉这棵树.重复这一过程直到所有树都被烧掉. 求走的总路程最多可以是多少. \(n\leq2\times10^5,\ a_i,L\leq10^9\). \(Solution\) 真的菜啊QAQ 当时连这个都不会 记顺时针走一次为\(L\),逆时针走一次为\(R\). 初步想法是\(LRLRLR.

AGC 030 B - Tree Burning 结论+枚举

考试 T2,是一个脑筋急转弯. 最暴力的贪心是每次先选左,再选右,再选左..... 然而这么做在一些情况下是错的. 但是,我们发现我们的选法一定是 $LLLLRLRLRLRLR$ 或 $RRRRLRLRLRLRLR$ (易证明) 所以直接枚举第一次向左/右走多少次,然后剩余的直接 $O(1)$ 计算即可. 原文地址:https://www.cnblogs.com/guangheli/p/11809014.html

【AtCoder】AGC030

A - Poisonous Cookies 有毒还吃,有毒吧 #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define MAXN 100005 #define e

AtCoder Beginner Contest 152 - F - Tree and Constraints (容斥定理+树上路径的性质)

AtCoder Beginner Contest 152 - F - Tree and Constraints (容斥定理+树上路径的性质) We have a tree with NN vertices numbered 11 to NN. The ii-th edge in this tree connects Vertex aiai and Vertex bibi. Consider painting each of these edges white or black. There ar

AtCoder 2376 Black and White Tree

D - Black and White Tree Time limit : 2sec / Memory limit : 256MB Score : 900 points Problem Statement There is a tree with N vertices numbered 1 through N. The i-th of the N?1 edges connects vertices ai and bi. Initially, each vertex is uncolored. T

AtCoder Grand Contest 014 E:Blue and Red Tree

题目传送门:https://agc014.contest.atcoder.jp/tasks/agc014_e 题目翻译 有一棵有\(N\)个点的树,初始时每条边都是蓝色的,每次你可以选择一条由蓝色边构成的简单路径,让这条路径的两个端点间连上一条红边,然后断开这条路径上的某条蓝边.这样做\(N-1\)次,就可以把原本的蓝树变成红树.现在给你蓝树和红树的样子,问你可不可能把给出的蓝树变成给出的红树.\(N\leqslant 10^5\) 题解 先膜一发大佬的题解:https://blog.csdn.

AtCoder Regular Contest 063 E:Integers on a Tree

题目传送门:https://arc063.contest.atcoder.jp/tasks/arc063_c 题目翻译 给你一个树,上面有\(k\)个点有权值,问你是否能把剩下的\(n-k\)个点全部填上权值,使得每条边链接的两个点权值相差\(1\),如果可以做到需要输出任意一组方案. 题解 我们考虑每条边权值为\(1\)或\(-1\),那么相当于黑白染色一样,所有点权值的奇偶性也都是确定的.如果与读入的\(k\)个点中某个点相冲突了就\(GG\).另外每个点的取值范围都可以转化成一段区间\([

AtCoder Regular Contest 093 E: Bichrome Spanning Tree(生成树)

Bichrome Spanning Tree 题意: 给出一个n个点,m条边的无向连通图,现在要给每条边染色,可以染成黑色或者白色. 现在要求在染色完毕后,找出一个至少包含一条黑边和一条白边的最小生成树,使其权值和为X. 问这样的染色方案有多少个? 题解: 题目要求找出一个至少包含一条黑边和白边的最小生成树,那么可能就会存在这种情况:原图的最小生成树所有边都为同色,那这不是我们要求的:我们这时就会去掉一条权值最大的边,再添一条边进来. 那么我们就可以算出包含指定边的最小生成树,方法就是先加我们指