AtCoderAGC020
Posted ivorysi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoderAGC020相关的知识,希望对你有一定的参考价值。
A - Move and Win
题解
看两个人相遇的时候谁先手即可,相遇之后第一个移动的人必输
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar(‘
‘)
#define space putchar(‘ ‘)
#define eps 1e-8
#define mo 974711
#define MAXN 2005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < ‘0‘ || c > ‘9‘) {
if(c == ‘-‘) f = -1;
c = getchar();
}
while(c >= ‘0‘ && c <= ‘9‘) {
res = res * 10 + c - ‘0‘;
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar(‘-‘);}
if(x >= 10) {
out(x / 10);
}
putchar(‘0‘ + x % 10);
}
int N,A,B;
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(N);read(A);read(B);
int t = abs(B - A - 1);
if(t & 1) puts("Alice");
else puts("Borys");
return 0;
}
B - Ice Rink Game
题解
二分直接判断即可
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar(‘
‘)
#define space putchar(‘ ‘)
#define eps 1e-8
#define mo 974711
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < ‘0‘ || c > ‘9‘) {
if(c == ‘-‘) f = -1;
c = getchar();
}
while(c >= ‘0‘ && c <= ‘9‘) {
res = res * 10 + c - ‘0‘;
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar(‘-‘);}
if(x >= 10) {
out(x / 10);
}
putchar(‘0‘ + x % 10);
}
int K;
int64 A[MAXN];
int64 check(int64 x) {
for(int i = 1 ; i <= K ; ++i) {
x -= x % A[i];
}
return x;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(K);
for(int i = 1 ; i <= K ; ++i) read(A[i]);
int64 L = 2,R = 1e18;
while(L < R) {
int64 mid = (L + R) >> 1;
if(check(mid) >= 2) R = mid;
else L = mid + 1;
}
if(check(R) != 2) {puts("-1");return 0;}
out(R);space;
R = 1e18;
while(L < R) {
int64 mid = (L + R + 1) >> 1;
if(check(mid) <= 2) L = mid;
else R = mid - 1;
}
out(R);enter;
}
C - Median Sum
题解
我们把子序列两两配对
也就是一个子序列选了其中的k个,另一个子序列选了其中的n - k个,进行配对
显然我们一个对内的子序列,肯定一个小于等于(frac{sum[n]}{2})
另一个大于等于(frac{sum[n]}{2})
由于全集没有配对,所以肯定中位数就是大于等于(frac{sum[n]}{2})的第一个
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar(‘
‘)
#define space putchar(‘ ‘)
#define eps 1e-8
#define mo 974711
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < ‘0‘ || c > ‘9‘) {
if(c == ‘-‘) f = -1;
c = getchar();
}
while(c >= ‘0‘ && c <= ‘9‘) {
res = res * 10 + c - ‘0‘;
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar(‘-‘);}
if(x >= 10) {
out(x / 10);
}
putchar(‘0‘ + x % 10);
}
int N,a[MAXN],s,cur;
bitset<4000005> dp[2];
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) {read(a[i]);s += a[i];}
dp[cur].reset();
dp[cur][0] = 1;
for(int i = 1 ; i <= N ; ++i) {
dp[cur ^ 1] = (dp[cur] << a[i]) | dp[cur];
cur ^= 1;
}
for(int i = (s - 1) / 2 + 1; i <= s ; ++i) {
if(dp[cur][i]) {
out(i);enter;return;
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
D - Min Max Repetition
题解
过于恶心的分类讨论题
首先我们用二分求出最小的k满足题意
求法可以是默认把A尽可能按k分块然后往能放的空隙里放B,之后默认把B尽可能按k分块然后能放的空隙里放A
之后呢,我们特判掉A和B分的段数不相等的情况
也就是A是1 1 1 1,B尽可能按k分块
B是1 1 1 1,A尽可能按k分块
之后A和B的段数就相等了
前面肯定是A有k个B有1个A有k个B有1个
后面肯定是A有1个B有k个A有1个B有k个
我们二分一个两者的段数
要求A第一个不为k的地方不可以在B第一个不为k之前两个
且长度最大
可以二分
然后我们把A的每段长度求出来,相同长度的记录一个重复次数
B同理
之后我们拿两个指针每段合并
合并的时候同时求一下这段如果要输出某一部分是哪里
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define pll pair<int64,int64>
#define mp make_pair
#define pb push_back
#define enter putchar(‘
‘)
#define space putchar(‘ ‘)
#define eps 1e-8
#define mo 974711
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < ‘0‘ || c > ‘9‘) {
if(c == ‘-‘) f = -1;
c = getchar();
}
while(c >= ‘0‘ && c <= ‘9‘) {
res = res * 10 + c - ‘0‘;
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar(‘-‘);}
if(x >= 10) {
out(x / 10);
}
putchar(‘0‘ + x % 10);
}
int64 A,B,C,D,ML;
vector<pll > vA,vB;
bool check(int64 a,int64 b,int64 k) {
int64 t = (a - 1) / k;
if(b < t) return false;
t += 2;
if(b > t * k) return false;
return true;
}
void Process(int64 l,int64 r) {
int p = 0,q = 0;
int64 len = 1;
int64 c = 0;
while(len <= ML) {
int64 t = min(vA[p].se,vB[q].se);
vA[p].se -= t;vB[q].se -= t;
if(len >= l) {
int64 k = t;
while(k--) {
for(int64 i = 1 ; i <= vA[p].fi ; ++i) {
putchar(‘A‘);++c;
if(c == r - l + 1) return;
}
for(int64 i = 1 ; i <= vB[q].fi ; ++i) {
putchar(‘B‘);++c;
if(c == r - l + 1) return;
}
}
}
else if(len + t * (vA[p].fi + vB[q].fi) - 1 >= l){
int64 k = (l - len) % (vA[p].fi + vB[q].fi) + 1;
int64 h = t - (l - len) / (vA[p].fi + vB[q].fi);
--h;
if(k <= vA[p].fi) {
for(int64 i = k ; i <= vA[p].fi ; ++i) {
putchar(‘A‘);++c;
if(c == r - l + 1) return;
}
for(int64 i = 1 ; i <= vB[q].fi ; ++i) {
putchar(‘B‘);++c;
if(c == r - l + 1) return;
}
}
else {
k -= vA[p].fi;
for(int64 i = k ; i <= vB[q].fi ; ++i) {
putchar(‘B‘);++c;
if(c == r - l + 1) return;
}
}
while(h--) {
for(int64 i = 1 ; i <= vA[p].fi ; ++i) {
putchar(‘A‘);++c;
if(c == r - l + 1) return;
}
for(int64 i = 1 ; i <= vB[q].fi ; ++i) {
putchar(‘B‘);++c;
if(c == r - l + 1) return;
}
}
}
len += t * (vA[p].fi + vB[q].fi);
if(vA[p].se == 0) ++p;
if(vB[q].se == 0) ++q;
}
}
void Solve() {
read(A);read(B);read(C);read(D);
int64 L = 1,R = max(A,B);
ML = (A + B);
while(L < R) {
int64 mid = (L + R) >> 1;
if(check(A,B,mid) || check(B,A,mid)) R = mid;
else L = mid + 1;
}
vA.clear();vB.clear();
if(A == ((B - 1) / L)) {
int64 t = B / L;
int64 rem = B - L * t;
vA.pb(mp(0,1));
vA.pb(mp(1,A));
if(rem) vB.pb(mp(rem,1));
vB.pb(mp(L,t));
}
else if(B == (A - 1) / L){
int64 t = A / L;
int64 rem = A - t * L;
vA.pb(mp(L,t));
if(rem) vA.pb(mp(rem,1));
vB.pb(mp(1,B));vB.pb(mp(0,1));
}
else {
int64 l = max((A - 1) / L + 1,(B - 1) / L + 1),r = min(A,B);
while(l < r) {
int64 m = (l + r + 1) >> 1;
int64 ta = (A - m) / (L - 1);
int64 tb = (B - m) / (L - 1);
ta = ta * 2 + 1;
tb = 2 * m - (tb * 2);
if(ta + 1 < tb) r = m - 1;
else l = m;
}
if(A > l) {
int64 ka = (A - l - 1) / (L - 1);
int64 rem = A - l - ka * (L - 1);
vA.pb(mp(L,ka));vA.pb(mp(1 + rem,1));vA.pb(mp(1,l - ka - 1));
}
else vA.pb(mp(1,l));
if(B > l) {
int64 kb = (B - l - 1) / (L - 1);
int64 rem = B - l - kb * (L - 1);
vB.pb(mp(1,l - kb - 1));vB.pb(mp(1 + rem,1));vB.pb(mp(L,kb));
}
else vB.pb(mp(1,l));
}
Process(C,D);
enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
int Q;
read(Q);
while(Q--) {
Solve();
}
}
E - Encoding Subsets
题解
这题很迷,复杂度很迷
记录(f(S))表示(S)字符串的答案
然后要么第一个字符不要(f(S) += (s[0] + 1)f(2...|S|))
要么就是我枚举一个长度,枚举一个压缩次数
每段都取一个按位且的值,然后计算这个字符串压缩方案数,之后再加上后面的字符串压缩方法
写起来容易一点可以写成记搜,然后用map记录每个string的答案
跑了不到2s,复杂度超级迷
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define pll pair<int64,int64>
#define mp make_pair
#define pb push_back
#define enter putchar(‘
‘)
#define space putchar(‘ ‘)
#define eps 1e-8
#define mo 974711
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < ‘0‘ || c > ‘9‘) {
if(c == ‘-‘) f = -1;
c = getchar();
}
while(c >= ‘0‘ && c <= ‘9‘) {
res = res * 10 + c - ‘0‘;
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar(‘-‘);}
if(x >= 10) {
out(x / 10);
}
putchar(‘0‘ + x % 10);
}
const int MOD = 998244353;
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
void update(int &x,int y) {
x = inc(x,y);
}
map<string,int> mm;
string operator & (const string &a,const string &b) {
int l = a.length();
string c(l,‘0‘);
for(int i = 0 ; i < l ; ++i) {
if(a[i] == ‘1‘ && b[i] == ‘1‘) c[i] = ‘1‘;
}
return c;
}
int dfs(string s) {
if(s.empty()) return 1;
if(s.length() == 1) return s[0] == ‘0‘ ? 1 : 2;
if(mm.count(s)) return mm[s];
int res = 0;
res = mul(s[0] == ‘1‘ ? 2 : 1,dfs(s.substr(1)));
int l = s.length();
for(int d = 1 ; d <= l ; ++d) {
string t = s.substr(0,d);
for(int k = d ; k <= l ; k += d) {
if(k + d - 1 >= l) break;
t = t & s.substr(k,d);
update(res,mul(dfs(t),dfs(s.substr(k + d))));
}
}
mm[s] = res;
return res;
}
void Solve() {
string s;
cin >> s;
out(dfs(s));enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}
F - Arcs on a Circle
题解
把最长的一段挑出来,一个端点作为0
然后把剩下(N - 1)放置的点的位置分成整数部分和小数部分
我们枚举一个排列,是N - 1个点小数的排列顺序,可以认为排列互不相同
然后可以抽象出(C * N)个点,第(i)行第(j)列表示整数部分是(i)小数部分排行为(j)
记录一个dp[a][b][S]表示当前在(a)点,最远能到b点,选了点状态为S
答案就是dp[C * N][C * N][2^{N - 1} - 1]
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define pll pair<int64,int64>
#define mp make_pair
#define pb push_back
#define enter putchar(‘
‘)
#define space putchar(‘ ‘)
#define eps 1e-8
#define mo 974711
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < ‘0‘ || c > ‘9‘) {
if(c == ‘-‘) f = -1;
c = getchar();
}
while(c >= ‘0‘ && c <= ‘9‘) {
res = res * 10 + c - ‘0‘;
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar(‘-‘);}
if(x >= 10) {
out(x / 10);
}
putchar(‘0‘ + x % 10);
}
int a[15],L[15],N,C;
bool vis[15];
int64 f[2][305][(1 << 5) + 5];
db ans,pw;
void Process() {
memset(f,0,sizeof(f));
int cur = 0;
f[cur][min(C * N,L[N] * N)][0] = 1;
for(int i = 1 ; i < C * N ; ++i) {
if(i % N == 0) continue;
memset(f[cur ^ 1],0,sizeof(f[cur ^ 1]));
int t = i % N - 1;
for(int j = i ; j <= C * N ; ++j) {
for(int k = 0 ; k < (1 << N - 1) ; ++k) {
if(!f[cur][j][k]) continue;
f[cur ^ 1][j][k] += f[cur][j][k];
if(k & (1 << t)) continue;
f[cur ^ 1][min(C * N,max(j,i + L[a[t + 1]] * N))][k ^ (1 << t)] += f[cur][j][k];
}
}
cur ^= 1;
}
ans += f[cur][C * N][(1 << N - 1) - 1];
}
void dfs(int dep) {
if(dep >= N) {
Process();return;
}
for(int i = 1 ; i < N ; ++i) {
if(!vis[i]) {
a[dep] = i;
vis[i] = 1;
dfs(dep + 1);
vis[i] = 0;
}
}
}
void Solve() {
read(N);read(C);
for(int i = 1 ; i <= N ; ++i) read(L[i]);
sort(L + 1,L + N + 1);
pw = 1;
for(int i = 1 ; i < N ; ++i) pw = pw * C;
dfs(1);
ans *= 1.0 / pw;
pw = 1.0;
for(int i = 2 ; i < N ; ++i) pw = pw * i;
ans *= 1.0 / pw;
printf("%.11lf
",ans);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}
以上是关于AtCoderAGC020的主要内容,如果未能解决你的问题,请参考以下文章