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+B0−A0&B0,然后就正选变反选。
然而这DP我也不会做,我为什么这么菜.jpg
状态极差,题解没看懂。扔这儿,周末填坑把。