首页 > 其他分享 >AtCoder Regular Contest 092 E Both Sides Merger

AtCoder Regular Contest 092 E Both Sides Merger

时间:2023-07-16 20:13:01浏览次数:50  
标签:AtCoder typedef Both Merger scd int maxn ans mx

洛谷传送门

AtCoder 传送门

Key observation:每个元素的下标奇偶性不改变。

于是讨论最后一个数是下标为奇数还是偶数加起来的数。将下标奇偶性相同的元素分开考虑。对于下标奇偶性相同的元素,不难发现答案的上界是所有 \(> 0\) 的元素之和(没有 \(> 0\) 的元素时选一个最大的),并且一定能够构造方案以达到上界。

例如,下面 O 代表对答案有贡献的元素,. 代表没有贡献的元素:

.O.O...O

方案是 .O.O...O \(\to\) O.O...O \(\to\) O...O \(\to\) O.O \(\to\) O

因为 \(n \le 10^3\),构造方案就直接模拟即可,复杂度 \(O(n^2)\)。

code
// Problem: E - Both Sides Merger
// Contest: AtCoder - AtCoder Regular Contest 092
// URL: https://atcoder.jp/contests/arc092/tasks/arc092_c
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 1010;

ll n, a[maxn], t1, t2;
pii b[maxn], c[maxn], d[maxn], e[maxn];
vector<int> ans;

inline void work(int i) {
	ans.pb(i);
	if (i == 1) {
		for (int i = 1; i < n; ++i) {
			d[i] = d[i + 1];
		}
		--n;
	} else if (i == n) {
		--n;
	} else {
		int m = 0;
		for (int j = 1; j <= n; ++j) {
			if (abs(j - i) <= 1) {
				if (j == i) {
					e[++m] = make_pair(d[i - 1].fst + d[i].fst + d[i + 1].fst, d[i - 1].scd);
				}
			} else {
				e[++m] = d[j];
			}
		}
		n = m;
		for (int i = 1; i <= n; ++i) {
			d[i] = e[i];
		}
	}
}

void solve() {
	scanf("%lld", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		if (i & 1) {
			b[++t1] = make_pair(a[i], i);
		} else {
			c[++t2] = make_pair(a[i], i);
		}
	}
	sort(b + 1, b + t1 + 1, greater<pii>());
	sort(c + 1, c + t2 + 1, greater<pii>());
	ll mx = -1e18, s = 0;
	for (int i = 1; i <= t1; ++i) {
		if (i > 1 && b[i].fst < 0) {
			break;
		}
		s += b[i].fst;
		mx = max(mx, s);
	}
	s = 0;
	for (int i = 1; i <= t2; ++i) {
		if (i > 1 && c[i].fst < 0) {
			break;
		}
		s += c[i].fst;
		mx = max(mx, s);
	}
	printf("%lld\n", mx);
	s = 0;
	for (int i = 1; i <= n; ++i) {
		d[i] = make_pair(a[i], 0);
	}
	for (int i = 1; i <= t1; ++i) {
		s += b[i].fst;
		if (s == mx) {
			for (int j = 1; j <= i; ++j) {
				d[b[j].scd].scd = 1;
			}
			while (!d[1].scd) {
				work(1);
			}
			for (int j = 2; j < n; ++j) {
				if (j > 1 && d[j - 1].scd == d[j + 1].scd) {
					work(j);
					j -= 2;
				}
			}
			while (!d[n].scd) {
				work(n);
			}
			printf("%d\n", (int)ans.size());
			for (int x : ans) {
				printf("%d\n", x);
			}
			return;
		}
	}
	s = 0;
	for (int i = 1; i <= t2; ++i) {
		s += c[i].fst;
		if (s == mx) {
			for (int j = 1; j <= i; ++j) {
				d[c[j].scd].scd = 1;
			}
			while (!d[1].scd) {
				work(1);
			}
			for (int j = 2; j < n; ++j) {
				if (j > 1 && d[j - 1].scd == d[j + 1].scd) {
					work(j);
					j -= 2;
				}
			}
			while (!d[n].scd) {
				work(n);
			}
			printf("%d\n", (int)ans.size());
			for (int x : ans) {
				printf("%d\n", x);
			}
			return;
		}
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,typedef,Both,Merger,scd,int,maxn,ans,mx
From: https://www.cnblogs.com/zltzlt-blog/p/17558439.html

相关文章

  • freee Programming Contest 2023(AtCoder Beginner Contest 310)
    freeeProgrammingContest2023(AtCoderBeginnerContest310)-AtCoderA-OrderSomethingElse(atcoder.jp)题意是在买一道菜的情况下可以将原为\(P\)元的饮料优惠到\(Q\)元,否则就按原价买#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;signed......
  • AtCoder Beginner Contest 310
    (AtCoderBeginnerContest310) A-OrderSomethingElse思路:比较下打折和不打折的情况#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>PII;typedefpair<string,int>PSI;typedefpair<string,string>PSS;c......
  • 近期 AtCoder Beginner Contest 题目选做
    AtCoderBeginnerContest310Ehttps://atcoder.jp/contests/abc310/tasks/abc310_e我们要求所有区间的NAND之和,发现NAND最后只可能是\(0\)或\(1\),所以我们只需要计数区间NAND为\(1\)的即可。考虑dp,设\(f_{i,0/1}\)表示以\(i\)结尾的区间最后NAND和为\(0/......
  • freee Programming Contest 2023(AtCoder Beginner Contest 310)题解
    点我看题A-OrderSomethingElse直接比较\(P\)和\(Q+min(D_i)\),输出较小值即可。点击查看代码#include<bits/stdc++.h>#definerep(i,n)for(inti=0;i<n;++i)#definerepn(i,n)for(inti=1;i<=n;++i)#defineLLlonglong#definefifirst#definesesecond#defi......
  • AtCoder Beginner Contest 310
    目录题目传送门:abc310比赛摘记:B题没读懂题意。。。如此简单题卡了好久继续加油哈......
  • Atcoder Regular Contest 118 F - Growth Rate
    想到插值其实就挺套路的了吧……设\(dp_{i,j}\)表示有多少种方法确定\(a_i\sima_n\)使得\(a_i=j\)。那么有\(dp_{i,j}=\sum\limits_{k\geja_i}dp_{i+1,k}\)。边界条件是\(dp_{n+1,1\simm}=1\)。不难发现复杂度与值域有关,一眼过不去的样子。考虑优化,记\(lim_i\)满足......
  • Atcoder AGC062C Mex of Subset Sum
    对\(a_i\)从小到大进行排序,因为想到若\(<a_{i-1}\)的不能取到的数因为\(a_i>a_{i-1}\)肯定是能保证取不到的。对排完序的\(a_i\)做一个前缀和\(s_i=\sum\limits_{j=1}^n\),令\(A_i\)为\(a_{1\simi}\)中无法表示为子序列之和且\(<s_i\)的正整数的集合......
  • AtCoder Beginner Contest 294
    A-Filter#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongint32_tmain(){ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);intn;cin>>n;for(intx;n;n--){cin>&......
  • AtCoder Beginner Contest 309 - D(最短路)
    目录D-AddOneEdge法一:dijkstra法二:BFS+队列题目传送门:abc309前面的简单题就不放了D-AddOneEdge题意:给你一个无向图图,分为两个连通块,一个顶点数为n1(1~n1),一个顶点数为n2(n1+1~n1+n2),图中共有m条边。如果现在在两个连通块之间连接一条边,那么顶点1与顶点n1+n2......
  • AtCoder Beginner Contest 162
    AtCoderBeginnerContest162ABCD全暴力E数学题看不懂,感性理解F线性dp,非常基础我不会,寄E-SumofgcdofTuples(Hard)看了题解发现好多做法都是推一堆式子,我实在看不懂(卷积莫反啥啥的呜呜呜)然后看见这个感觉比较好感性理解:(来自洛谷题解)#include<bits/stdc++.h>#def......