【AtCoder】M-SOLUTIONS Programming Contest

泪湿孤枕 提交于 2020-12-13 14:30:08

M-SOLUTIONS Programming Contest

A - Sum of Interior Angles

#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 eps 1e-10
#define MAXN 200005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    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;
void Solve() {
    read(N);
    out((N - 2) * 180);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

B - Sumo

#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 eps 1e-10
#define MAXN 200005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    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 L;
char s[20];
void Solve() {
    scanf("%s",s + 1);
    L = strlen(s + 1);
    int ans = 15 - L;
    for(int i = 1 ; i <= L ; ++i) {
        if(s[i] == 'o') ++ans;
    }
    if(ans >= 8) puts("YES");
    else puts("NO");
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

C - Best-of-(2n-1)

就是有$C$的概率往下摁,否则就停止,这样的期望次数是$\frac{C}{1 - C}$

我们枚举最终情况走了$i$个$A$和$N$个$B$(反过来同理),这个时候$A$胜的概率是$\frac{A}{A+ B}$,$B$胜的概率是$\frac{B}{A+ B}$,期望次数就是$(N + i)(\frac{C}{1 - C} + 1)$

#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 eps 1e-10
#define MAXN 100005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    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 = 1000000007;
int fac[1000005],invfac[1000005];
int N,A,B,C;
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 &a,int b) {
    a = inc(a,b);
}
int cnm(int n,int m) {
    if(n < m) return 0;
    else return mul(fac[n],mul(invfac[m],invfac[n - m]));
}
int fpow(int x,int c) {
    int res = 1,t = x;
    while(c) {
        if(c & 1) res = mul(res,t);
        t = mul(t,t);
        c >>= 1;
    }
    return res;
}
void Solve() {
    read(N);read(A);read(B);read(C);
    A = mul(A,fpow(100,MOD - 2));
    B = mul(B,fpow(100,MOD - 2));
    C = mul(C,fpow(100,MOD - 2));
    int iv = fpow(inc(1,MOD - C),MOD - 2);
    C = mul(C,iv);
    int k = fpow(inc(A,B),MOD - 2);
    A = mul(A,k);B = mul(B,k);
    fac[0] = 1;
    for(int i = 1 ; i <= 2 * N ; ++i) {
        fac[i] = mul(fac[i - 1],i);
    }
    invfac[2 * N] = fpow(fac[2 * N],MOD - 2);
    for(int i = 2 * N - 1 ; i >= 0 ; --i) {
        invfac[i] = mul(invfac[i + 1],i + 1);
    }
    int ans = 0;
    for(int i = 0 ; i < N ; ++i) {
        int h = inc(mul(fpow(A,N),fpow(B,i)),mul(fpow(B,N),fpow(A,i)));
        int t = mul(cnm(i + N - 1,N - 1),mul(C + 1,i + N));
        t = mul(t,h);
        update(ans,t);
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

D - Maximum Sum of Minimum

大胆猜想一下发现就是除了最大值都加一遍,如果一个值加了两遍会占一个比它大的值得位置,不优,构造的话就是随便选一个根然后按dfs序从大到小填数

#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 eps 1e-10
#define MAXN 10005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    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);
}
struct node {
    int to,next;
}E[MAXN * 2];
int sumE,head[MAXN],N;
int c[MAXN],ans;
int p[MAXN],tot;
void add(int u,int v) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    head[u] = sumE;
}
void dfs(int u,int fa) {
    p[u] = c[tot--];
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(v != fa) {
            dfs(v,u);
        }
    }
}
void Solve() {
    read(N);
    int a,b;
    for(int i = 1 ; i < N ; ++i) {
        read(a);read(b);add(a,b);add(b,a);
    }
    for(int i = 1 ; i <= N ; ++i) read(c[i]);
    sort(c + 1,c + N + 1);
    for(int i = 1 ; i < N ; ++i) ans += c[i];
    tot = N;
    dfs(1,0);
    out(ans);enter;
    for(int i = 1 ; i <= N ; ++i) {
        out(p[i]);space;
    }
    enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

E - Product of Arithmetic Progression

没做出来的我真是降智

如果d=0,那么答案是$x^{n}$

如果d不为0,都除上一个d,然后发现是一段连续的数相乘,可以用前缀乘积的一个除另一个,特判掉$x = 0$和$\frac{x}{d} + n - 1 >= P$的情况,最后再乘上$d^{n}$

#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 eps 1e-10
#define MAXN 10005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    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 = 1000003;

int pre[MOD + 5];
int mul(int a,int b) {
    return 1LL * a * b % MOD;
}
int inc(int a,int b) {
    return a + b >= MOD ? a + b - MOD : a + b;
}
int fpow(int x,int c) {
    int res = 1,t = x;
    while(c) {
        if(c & 1) res = mul(res,t);
        t = mul(t,t);
        c >>= 1;
    }
    return res;
}
void Solve() {
    pre[0] = 1;
    for(int i = 1 ; i < MOD ; ++i) pre[i] = mul(pre[i - 1],i);
    int Q,x,d,n;
    read(Q);
    for(int i = 1 ; i <= Q ; ++i) {
        read(x);read(d);read(n);
        if(d == 0) {out(fpow(x,n));enter;continue;}
        x = mul(x,fpow(d,MOD - 2));
        if(x + n - 1 >= MOD || x == 0) {puts("0");continue;}
        int res = mul(pre[x + n - 1],fpow(pre[x - 1],MOD - 2));
        res = mul(res,fpow(d,n));
        out(res);enter;
    }
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

F - Random Tournament

设$dpl[i][j]$表示这个区间$[i,j]$有一种方式是$i$能打败所有人

$dpr[i][j]$表示有一种方式$j$能打败所有人

答案就是$dpr[1][x] = 1$并且$dpl[x][N] = 1$的所有位置

然后$dpr[l][r]$为1的条件是存在$k$使得$dpr[l][k] = 1$并且$dpl[k][r - 1] = 1$并且$a_{r,k} = 1$

$dpl[l][r]$是存在$k$使得$dpr[l + 1][k] = 1$并且$dpl[k][r] = 1$并且$a_{l,k} = 1$

这个可以用bitset优化,所以复杂度是$O(\frac{N^{3}}{w})$

#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 eps 1e-10
#define MAXN 10005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    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);
}
bitset<2005> a[2005],dpr[2005],dpl[2005],tmp;
int N;
char s[2005][2005];
void Solve() {
    read(N);
    for(int i = 2 ; i <= N ; ++i) {
        scanf("%s",s[i] + 1);
        for(int j = 1 ; j < i ; ++j) {
            if(s[i][j] == '1') a[i][j] = 1;
            else a[j][i] = 1;
        }
    }
    for(int i = 1 ; i <= N ; ++i) dpr[i][i] = 1,dpl[i][i] = 1;
    for(int d = 2 ; d <= N ; ++d) {
        for(int l = 1 ; l <= N ; ++l) {
            int r = l + d - 1;
            if(r > N) break;
            if((dpr[l] & dpl[r - 1] & a[r]).any()) {
                dpr[l][r] = 1;
            }
            if((dpl[r] & dpr[l + 1] & a[l]).any()) {
                dpl[r][l] = 1;
            }
        }
    }
    out((dpr[1] & dpl[N]).count());enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!