ARC085简要题解

博主分享了参加ARC084算法竞赛的经历,详细记录了解题思路和过程。涉及模意义最短路、找规律、线段树、最大权闭合子图等算法问题,并对部分题目给出了代码实现。此外,还提到了一些复杂题目在实际解决中遇到的困难,如实数运算、动态规划等。
摘要由CSDN通过智能技术生成

ARC084是昨天晚上看FPX打RA的时候写的(
感觉题有点拉,就没写题解。
一个模意义最短路,一个显然是找规律(但是不想找了,比赛太好看
这个是今天的图
在这里插入图片描述
打的感觉一般吧,T2卡了,然后去过了T3的网络流,之后玩了玩T2,猜了个结论过了。
T4看到就感觉有一股很浓的线段树味,转了一步之后发觉那个DP我不会,然后凉凉。

C题:
他居然让我用实数.jpg
然后就搞了个模拟1w次(

#include <bits/stdc++.h>
using namespace std;
int n, m;
double bp, p;
double ans;
int main() { 
	cin>>n>>m;
	bp = 0.50, p = 1.00;
	double np = 1;
	for(int i=1;i<=m;++i) { 
		p = p * bp;
	} 
	double nval = 1900 * m + 100 * (n - m);
	for(int i=1;i<=10000;++i) { 
		ans += nval * i * (np * p);
		np = np * (1 - p);
	}
	printf("%.0lf",ans);
	return 0;
} 

D题:
手玩了一会儿,发现答案总是这两个里面的一个。
猜了一发,交了一发,过了。
原理暂时还没想通。

#include<bits/stdc++.h>
using namespace std;
int n;
int A, B;
int val[20010];

signed main() { 
	cin>>n>>A>>B;
	for(int i=1;i<=n;++i) 
		scanf("%d", &val[i]);
	long long ans = 0;
	ans = max(ans,1ll * abs(val[n] - B));
	if(n > 1)
		ans = max(ans,1ll * abs(val[n-1] - val[n]));
	cout<<ans;
	return 0;
} 

E题:
“选A必须选B”——最大权闭合子图。
只不过这题要取反变成“干掉A必须干掉B”。
于是去个反,做最大权闭合子图就行了。
唔顺便:
“选A必须选B”——最大权闭合子图:原图边变INF
如果val[p] > 0,则ade(SS, p, val[p])
如果val[p] < 0,则ade(p, TT, -val[p])
最大权闭合子图的权值等于所有正权点的权值和-最小割。
考虑原理,如果是个正权点,割了他相当于不选。
如果是个负权点,割了他相当于选。
而如果网络流的图里连通了,说明存在一个“选了前驱没选后继”,不符合原问题要求。

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace Maxflow {
	struct edge {
		int to;
		long long flow;
		int op;
	}; vector<edge>ed[10010];
	int ly[10010],cur[10010]; queue<int>sth;
	inline void ade(int l, int r, long long f) {
		ed[l].push_back({r,f,(int)ed[r].size()});
		ed[r].push_back({l,0,(int)ed[l].size()-1});
	}
	inline bool bfs(int S, int T) {
		memset(cur,0,sizeof(cur)),memset(ly,0,sizeof(ly)), ly[S] = 1, sth.push(S);
		while(!sth.empty()) { int nw = sth.front(); sth.pop();
			for(int i=0;i<ed[nw].size();++i) {
				int tar = ed[nw][i].to;
				if(ed[nw][i].flow == 0 || ly[tar]) continue;
				ly[tar] = ly[nw] + 1, sth.push(tar);
			}
		} return ly[T] != 0;
	}
	inline int dfs(int nw, int ftar, long long nflow) {
		if(nw == ftar) return nflow;
		long long ret = 0;
		for(int i=cur[nw];i<ed[nw].size();++i) { cur[nw] = i;
			int tar = ed[nw][i].to;
			if(ly[tar] != ly[nw] + 1) continue;
			long long ncanf = dfs(tar, ftar, min(nflow - ret, ed[nw][i].flow));
			ed[nw][i].flow -= ncanf, ed[tar][ed[nw][i].op].flow += ncanf;
			ret += ncanf; if(ret == nflow) break;
		} return ret;
	}
	inline long long dinic(int S, int T) { long long ret = 0;
		while(bfs(S,T))
			ret += dfs(S,T,0x3f3f3f3f3f3f3f3f);
		return ret;
	}
} using namespace Maxflow;

int n;
int a[123];
long long sum;
int SS, TT;
signed main() { 
	scanf("%lld", &n);
	SS = 105, TT = 106;
	for(int i=1;i<=n;++i) { 
		scanf("%lld", &a[i]);
		sum += a[i];
	} 
	for(int i=1;i<=n;++i) 
		for(int j=i+1;j<=n;++j) 
			if(j % i == 0) 
				ade(i, j, 0x3f3f3f3f3f3f);
	long long det = 0;
	for(int i=1;i<=n;++i) { 
		if(a[i] < 0) 
			ade(SS, i, -a[i]), det -= a[i];
		if(a[i] > 0) 
			ade(i, TT, a[i]);
	} 
	det -= dinic(SS, TT);
	cout<<sum + det;
	return 0;
} 

F赛时:
想到了这个可以给A整体XOR上一个B的操作。
然后变为有个数列,里头有值分别是1 -1,区间覆盖一下。
发觉DP不会做。
然后发觉那问题目测能做±1就能做所有的,他给我01串多半不是拿来干这个的。
想了想01串的特性,列了列情况,转了一步, A N S = A 0 & B 1 + A 1 & B 0 = A 0 & B 1 + B 0 − A 0 & B 0 ANS=A_0\&B_1 + A_1\&B_0=A_0\&B_1+B_0-A_0\&B_0 ANS=A0&B1+A1&B0=A0&B1+B0A0&B0,然后就正选变反选。
然而这DP我也不会做,我为什么这么菜.jpg

状态极差,题解没看懂。扔这儿,周末填坑把。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值