CodeForces Gym 101615简要题解

Odd Palindrome

签到。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    string s;
    cin >> s;
    for (int i = 1; i < s.length(); i ++)
        if (s[i] == s[i - 1])
            return puts("Or not."), 0;
    return puts("Odd."), 0;
}

Enlarging Enthusiasm

f(s,p,c) 表示当前状态为 s ,上一个人是p,当前还剩 c 的分数。

每次枚举下一个人i,那么需要加的分是 max(apai+1,0) ,因为 q 单调,所以在这里直接减掉。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const int MAXN = 15;
const int MAXM = 705;
const int MAXS = 4100;

int n, m, s, a[MAXN], f[MAXS][MAXN][MAXM];

inline int DFS(int s, int p, int c)
{
    if (c < 0)
        return 0;
    if (s == (1 << n) - 1)
        return 1;
    if (~f[s][p][c])
        return f[s][p][c];
    f[s][p][c] = 0;
    for (int i = 0; i < n; i ++)
        if (!(s >> i & 1))
            f[s][p][c] += DFS(s | 1 << i, i, c - max(a[p] - a[i] + 1, 0) * (n - __builtin_popcount(s)));
    return f[s][p][c];
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    n = Read(), s = Read();
    for (int i = 0; i < n; i ++)
        m = max(m, a[i] = Read());
    mset(f, -1);
    int ans = 0;
    for (int i = 0; i < n; i ++)
        if (a[i] ^ m)
            ans += DFS(1 << i, i, s - (m - a[i] + 1) * n);
    return printf("%d\n", ans), 0;
}

Fear Factoring

考虑每个约数贡献,下底函数分块之后等差数列求和。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

inline LL Solve(LL n)
{
    LL ret = 0;
    for (LL l = 1, r; l <= n; l = r + 1)
        r = n / (n / l), ret += (l + r) * (r - l + 1) * (n / l);
    return ret;
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    LL a, b;
    scanf("%lld %lld", &a, &b);
    return printf("%lld\n", Solve(b) - Solve(a - 1) >> 1), 0;
}

Rainbow Roads

枚举一个点,如果跟他相连的有两条相邻颜色的边,那么这两个子树都不是好的,求出DFS序之后打差分标记。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const int MAXN = 50005;

int n, tim, seq[MAXN], dfn[MAXN], siz[MAXN], par[MAXN], sum[MAXN];
vector <pii> adj[MAXN];

inline void DFS(int x)
{
    siz[x] = 1, seq[dfn[x] = ++ tim] = x;
    for (auto e : adj[x])
        if (e.yy ^ par[x])
            par[e.yy] = x, DFS(e.yy), siz[x] += siz[e.yy];
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    n = Read();
    for (int i = 1, x, y, w; i < n; i ++)
        x = Read(), y = Read(), w = Read(), adj[x].pb(mp(w, y)), adj[y].pb(mp(w, x));
    DFS(1);
    for (int i = 1; i <= n; i ++)
    {
        sort(adj[i].begin(), adj[i].end());
        for (int l = 0, r = 0; l < adj[i].size(); l = r)
        {
            while (r < adj[i].size() && adj[i][r].xx == adj[i][l].xx)
                r ++;
            if (r - l ^ 1)
            {
                for (int j = l; j < r; j ++)
                    if (adj[i][j].yy == par[i])
                        sum[1] ++, sum[dfn[i]] --, sum[dfn[i] + siz[i]] ++;
                    else
                        sum[dfn[adj[i][j].yy]] ++, sum[dfn[adj[i][j].yy] + siz[adj[i][j].yy]] --;
            }
        }
    }
    vector <int> ans;
    for (int i = 1; i <= n; i ++)
        if (!(sum[i] += sum[i - 1]))
            ans.pb(seq[i]);
    printf("%d\n", ans.size());
    sort(ans.begin(), ans.end());
    for (auto x : ans)
        printf("%d\n", x);
    return 0;
}

Straight Shot

二分水平速度。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const int MAXN = 105;
const double eps = 1e-9;

int n, x, l[MAXN], r[MAXN];
double v, w[MAXN];

inline double Chk(double mid)
{
    double d = sqrt(v * v - mid * mid), ret = -x / mid * d;
    for (int i = 1; i <= n; i ++)
        ret += (r[i] - l[i]) / mid * w[i];
    return ret;
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    n = Read(), x = Read(), scanf("%lf", &v);
    double delta = 0;
    for (int i = 1; i <= n; i ++)
        l[i] = Read(), r[i] = Read(), scanf("%lf", &w[i]), delta += (r[i] - l[i]) / v * w[i];
    if (fabs(delta) < eps)
        return printf("%.3lf\n", x / v), 0;
    if (delta < 0)
        for (int i = 1; i <= n; i ++)
            w[i] = -w[i];
    double l = v / 2, r = v;
    for (int i = 1; i <= 100; i ++)
    {
        double mid = (l + r) / 2;
        if (Chk(mid) < 0)
            l = mid;
        else
            r = mid;
    }
    if (fabs(Chk(l)) < eps)
        return printf("%.3lf\n", x / l), 0;
    return puts("Too hard"), 0;
}

Distinct Distances

答案是两个点中点或者两条垂直平分线交点。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const double eps = 1e-9;

inline int Sgn(double x) { return fabs(x) < eps ? 0 : x > 0 ? 1 : -1; }
inline int Cmp(double x, double y) { return Sgn(x - y); }
inline bool Mid(double l, double r, double mid) { return Cmp(l, mid) * Cmp(r, mid) <= 0; }

struct Point
{
    double x, y;
    Point(double _x = 0, double _y = 0) { x = _x, y = _y; }
    Point operator + (const Point &b) const { return Point(x + b.x, y + b.y); }
    Point operator - (const Point &b) const { return Point(x - b.x, y - b.y); }
    Point operator * (const double &b) const { return Point(x * b, y * b); }
    Point operator / (const double &b) const { return Point(x / b, y / b); }
    double operator * (const Point &b) const { return x * b.x + y * b.y; }
    double operator ^ (const Point &b) const { return x * b.y - y * b.x; }
    bool operator == (const Point &b) const { return !Cmp(x, b.x) && !Cmp(y, b.y); }
    bool operator != (const Point &b) const { return Cmp(x, b.x) || Cmp(y, b.y); }
    inline double Len() { return x * x + y * y; }
};

inline double Dis(Point x, Point y) { return sqrt((x - y).Len()); }
inline bool Mid(Point l, Point r, Point mid) { return Mid(l.x, r.x, mid.x) && Mid(l.y, r.y, mid.y); }

inline bool Intersect_Line(Point l1, Point r1, Point l2, Point r2)
{
    return Cmp((l2 - l1) ^ (r2 - l1), (l2 - r1) ^ (r2 - r1));
}

inline Point Get_Intersect(Point l1, Point r1, Point l2, Point r2)
{
    double w1 = (l1 - l2) ^ (r2 - l2), w2 = (r2 - l2) ^ (r1 - l2);
    return (l1 * w2 + r1 * w1) / (w1 + w2);
}

const int MAXN = 45;

int n, ans;
double d[MAXN];
Point a[MAXN];

inline void Solve(Point p)
{
    for (int i = 1; i <= n; i ++)
        d[i] = Dis(a[i], p);
    sort(d + 1, d + n + 1);
    int ret = 1;
    for (int i = 2; i <= n; i ++)
        ret += Cmp(d[i], d[i - 1]);
    ans = min(ans, ret);
}

inline pair <Point, Point> Get(Point a, Point b)
{
    Point c = (a + b) / 2, d = b - a;
    return mp(c, Point(c.x - d.y, c.y + d.x));
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    n = ans = Read();
    for (int i = 1; i <= n; i ++)
        a[i].x = Read(), a[i].y = Read();
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= n; j ++)
            Solve((a[i] + a[j]) / 2);
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j < i; j ++)
            for (int k = 1; k <= n; k ++)
                for (int l = 1; l < k; l ++)
                {
                    auto p = Get(a[i], a[j]).xx, q = Get(a[i], a[j]).yy, r = Get(a[k], a[l]).xx, s = Get(a[k], a[l]).yy;
                    if (Intersect_Line(p, q, r, s))
                        Solve(Get_Intersect(p, q, r, s));
                }
    return printf("%d\n", ans), 0;
}

Security Badge

离散化之后暴力BFS。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const int MAXN = 1005;
const int MAXM = 10005;

int n, m, c, k, s, t, ans, l[MAXM];
vector <pair <int, pii>> adj[MAXN];
bool vis[MAXN];

inline void DFS(int x, int v)
{
    vis[x] = 1;
    for (auto e : adj[x])
        if (v >= e.yy.xx && v <= e.yy.yy && !vis[e.xx])
            DFS(e.xx, v);
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    n = Read(), m = Read(), l[++ c] = k = Read(), s = Read(), t = Read();
    for (int i = 1, x, y, w, v; i <= m; i ++)
        x = Read(), y = Read(), w = Read(), v = Read(), l[++ c] = w - 1, l[++ c] = v, adj[x].pb(mp(y, mp(w, v)));
    sort(l + 1, l + c + 1), c = unique(l + 1, l + c + 1) - l - 1;
    for (int i = 1; i <= c; i ++)
    {
        for (int j = 1; j <= n; j ++)
            vis[j] = false;
        DFS(s, l[i]);
        if (vis[t])
            ans += l[i] - l[i - 1];
        if (l[i] == k)
            return printf("%d\n", ans), 0;
    }
    return 0;
}

Avoiding Airports

扫描线维护时间,fe表示最后一次是 e 这条边的最小代价,斜率优化。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const int MAXN = 200005;
const LL INF = 1LL << 60;

int n, m, d[MAXN], u[MAXN], v[MAXN], w[MAXN], z[MAXN], ql[MAXN], qr[MAXN];
vector <pair <int, LL>> vec[MAXN];
vector <int> eve[MAXN * 5];
LL f[MAXN];

inline void Insert(int p, int x, LL y)
{
    if (y >= INF)
        return ;
    if (ql[p] <= qr[p] && vec[p][qr[p]].xx == x)
    {
        if (vec[p][qr[p]].yy <= y)
            return ;
        qr[p] --;
    }
    while (ql[p] < qr[p] && (vec[p][qr[p]].xx - vec[p][qr[p] - 1].xx) * (y - vec[p][qr[p]].yy) <= (x - vec[p][qr[p]].xx) * (vec[p][qr[p]].yy - vec[p][qr[p] - 1].yy))
       qr[p] --;
    vec[p][++ qr[p]] = mp(x, y);
}

inline LL Query(int p, int k)
{
    if (ql[p] > qr[p])
        return INF;
    while (ql[p] < qr[p] && vec[p][ql[p]].yy - 1LL * k * vec[p][ql[p]].xx >= vec[p][ql[p] + 1].yy - 1LL * k * vec[p][ql[p] + 1].xx)
        ql[p] ++;
    return vec[p][ql[p]].yy - 1LL * k * vec[p][ql[p]].xx;
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    n = Read(), m = Read(), d[1] = 1;
    for (int i = 1; i <= m; i ++)
        u[i] = Read(), v[i] = Read(), w[i] = Read(), z[i] = Read(), d[v[i]] ++, eve[w[i]].pb(-i), eve[z[i]].pb(i);
    for (int i = 1; i <= n; i ++)
        vec[i].resize(d[i] + 1), qr[i] = -1;
    Insert(1, 0, 0);
    for (int i = 0; i <= 1000000; i ++)
        for (auto x : eve[i])
            if (x < 0)
            {
                x = -x;
                f[x] = Query(u[x], w[x]);
                if (f[x] < INF)
                    f[x] += 1LL * w[x] * w[x];
            }
            else
                Insert(v[x], z[x] << 1, 1LL * z[x] * z[x] + f[x]);
    LL ans = INF;
    for (int i = 1; i <= m; i ++)
        if (v[i] == n)
            ans = min(ans, f[i]);
    return printf("%lld\n", ans), 0;
}

Long Long Strings

初始弄一个从26开始的无穷递增数列,用set压缩区间,暴力维护。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline LL Read()
{
    LL x = 0; int f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const LL INF = 1LL << 40;

struct Node
{
    LL l, r, v;

    Node(LL _l = 0, LL _r = 0, LL _v = 0)
    {
        l = _l, r = _r, v = _v;
    }

    bool operator < (const Node &b) const
    {
        return l < b.l || (l == b.l && r < b.r) || (l == b.l && r == b.r && v < b.v);
    }
};

set <Node> s1, s2;

inline void Solve(set <Node> &s)
{
    s.insert(Node(0, INF, 26));
    char opt[10];
    while (true)
    {
        scanf("%s", opt);
        if (opt[0] == 'D')
        {
            LL x = Read(), l, r, v;
            auto it = -- s.upper_bound(Node(x + 1, 0, 0)), jt = it;
            l = it -> l, r = it -> r, v = it -> v, jt ++, s.erase(it);
            vector <Node> vec;
            if (l ^ x)
                vec.pb(Node(l, x - 1, v));
            if (x ^ r)
                vec.pb(Node(x, r - 1, v - l + x + 1));
            while (jt != s.end())
                l = jt -> l, r = jt -> r, v = jt -> v, s.erase(jt ++), vec.pb(Node(l - 1, r - 1, v));
            for (auto x : vec)
                s.insert(x);
        }
        else if (opt[0] == 'I')
        {
            LL x = Read() - 1, l, r, v, t;
            scanf("%s", opt), t = opt[0] - 'A';
            auto it = -- s.upper_bound(Node(x + 1, 0, 0)), jt = it;
            l = it -> l, r = it -> r, v = it -> v, jt ++, s.erase(it);
            vector <Node> vec;
            vec.pb(Node(l, x, v));
            if (x ^ r)
                vec.pb(Node(x + 2, r + 1, v - l + x + 1));
            vec.pb(Node(x + 1, x + 1, t));
            while (jt != s.end())
                l = jt -> l, r = jt -> r, v = jt -> v, s.erase(jt ++), vec.pb(Node(l + 1, r + 1, v));
            for (auto x : vec)
                s.insert(x);
        }
        else
            break;
    }
}

inline bool Chk(set <Node> a, set <Node> b)
{
    while (!a.empty() || !b.empty())
    {
        if (a.empty() || b.empty())
            return true;
        auto it = a.begin(), jt = b.begin();
        if (it -> l != jt -> l || it -> v != jt -> v)
            return true;
        if (it -> r == jt -> r)
            a.erase(it), b.erase(jt);
        else if (it -> r < jt -> r)
            b.insert(Node(it -> r + 1, jt -> r, jt -> v - it -> l + it -> r + 1)), a.erase(it), b.erase(jt);
        else
            a.insert(Node(jt -> r + 1, it -> r, it -> v - jt -> l + jt -> r + 1)), a.erase(it), b.erase(jt);
    }
    return false;
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    Solve(s1), Solve(s2);
    return printf("%d\n", Chk(s1, s2)), 0;
}

Grid Coloring

f(i,j) 表示前 i 行,最后一个B是j的方案数。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const int MAXN = 35;

int n, m, l[MAXN], r[MAXN];
LL f[MAXN][MAXN];
char s[MAXN];

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    n = Read(), m = Read();
    for (int i = 1; i <= n; i ++)
    {
        scanf("%s", s + 1);
        int p = 0;
        for (int j = 1; j <= m; j ++)
            if (s[j] == 'B')
                p = j;
        if (!p)
        {
            l[i] = 0;
            for (int j = 1; j <= m; j ++)
                if (s[j] == 'R')
                    r[i] = j - 1, j = m + 1;
                else if (j == m)
                    r[i] = m;
        }
        else
        {
            for (int j = 1; j <= p; j ++)
                if (s[j] == 'R')
                    return puts("0"), 0;
            l[i] = p;
            for (int j = p; j <= m; j ++)
                if (s[j] == 'R')
                    r[i] = j - 1, j = m + 1;
                else
                    r[i] = m;
        }
    }
    f[0][m] = 1;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j <= m; j ++)
            if (f[i][j])
                for (int k = l[i + 1]; k <= r[i + 1] && k <= j; k ++)
                    f[i + 1][k] += f[i][j];
    LL ret = 0;
    for (int i = 0; i <= m; i ++)
        ret += f[n][i];
    return printf("%lld\n", ret), 0;
}

Spinning Up Palindromes

从两边往中间DP, f(i,0/1,0/1) 表示前 i 位,是否需要进位,后几位是否进位的最小代价。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const int MAXN = 45;
const int INF = 0x3f3f3f3f;

int n, ans = INF, a[MAXN], f[MAXN][2][2];
char s[MAXN];

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    scanf("%s", s + 1), n = strlen(s + 1);
    for (int i = 1; i <= n; i ++)
        a[i] = s[i] - '0';
    mset(f, 0x3f), f[0][1][0] = f[0][0][0] = 0;
    for (int l = 1, r = n; l < r; l ++, r --)
        for (int i = 0; i < 2; i ++)
            for (int j = 0; j < 2; j ++)
                if (f[l - 1][i][j] ^ INF)
                    for (int k = 0; k < 2; k ++)
                        for (int x = 0; x < 10; x ++)
                            for (int y = 0; y < 10; y ++)
                            {
                                int u = a[l] + x + k, v = a[r] + y + j, m = v > 9;
                                if ((u > 9) ^ i)
                                    continue;
                                if (u > 9)
                                    u -= 10;
                                if (v > 9)
                                    v -= 10;
                                if (u == v)
                                    f[l][k][m] = min(f[l][k][m], f[l - 1][i][j] + x + y);
                            }
    if (!(n & 1))
        for (int i = 0; i < 2; i ++)
            ans = min(ans, f[n >> 1][i][i]);
    else
        for (int i = 0; i < 2; i ++)
            for (int j = 0; j < 2; j ++)
                for (int x = 0; x < 10; x ++)
                    if ((a[n + 1 >> 1] + x + j) / 10 == i)
                        ans = min(ans, f[n >> 1][i][j] + x);
    return printf("%d\n", ans), 0;

}

Delayed Work

暴力。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    int k = Read(), p = Read(), x = Read();
    double ans = 1e9;
    for (int i = 1; i <= 10000; i ++)
        ans = min(ans, (double)k * p / i + x * i);
    return printf("%.3lf\n", ans), 0;
}

Unsatisfying

如果没有¬i¬j的限制,那么显然无解。

如果原来2-SAT就无解那么显然无解了,不然最优解一定是加 ii 这种形式,显然答案不超过 2 ,枚举每个点,判断答案是否为1就行了。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
    int x = 0, f = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (;  isdigit(c); c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

const int MAXN = 4005;

int n, m, tim, top, cnt, sta[MAXN], dfn[MAXN], low[MAXN], scc[MAXN];
vector <int> adj[MAXN], adv[MAXN];

inline void DFS(int x)
{
    sta[++ top] = x, dfn[x] = low[x] = ++ tim;
    for (auto y : adj[x])
        if (!dfn[y])
            DFS(y), low[x] = min(low[x], low[y]);
        else if (!scc[y])
            low[x] = min(low[x], dfn[y]);
    if (low[x] == dfn[x])
    {
        int k = 0;
        for (cnt ++; k ^ x; scc[k = sta[top --]] = cnt);
    }
}

int main()
{
#ifdef wxh010910
    freopen("data.in", "r", stdin);
#endif
    n = Read(), m = Read();
    bool flg = false;
    for (int i = 1; i <= m; i ++)
    {
        int x = Read(), y = Read();
        flg |= x < 0 && y < 0;
        if (x < 0)
            x = n - x;
        if (y < 0)
            y = n - y;
        if (x <= n)
            adv[x + n].pb(y);
        else
            adv[x - n].pb(y);
        if (y <= n)
            adv[y + n].pb(x);
        else
            adv[y - n].pb(x);
    }
    if (!flg)
        return puts("-1"), 0;
    for (int i = 1; i <= n << 1; i ++)
        for (auto j : adv[i])
            adj[i].pb(j);
    for (int i = 1; i <= n << 1; i ++)
        if (!dfn[i])
            DFS(i);
    for (int i = 1; i <= n; i ++)
        if (scc[i] == scc[i + n])
            return puts("0"), 0;
    for (int i = 1; i <= n; i ++)
    {
        for (int j = 1; j <= n << 1; j ++)
            adj[j].clear(), dfn[j] = low[j] = scc[j] = 0;
        tim = cnt = 0;
        for (int j = 1; j <= n << 1; j ++)
            for (auto k : adv[j])
                adj[j].pb(k);
        adj[i + n].pb(i);
        for (int j = 1; j <= n << 1; j ++)
            if (!dfn[j])
                DFS(j);
        for (int j = 1; j <= n; j ++)
            if (scc[j] == scc[j + n])
                return puts("1"), 0;
    }
    return puts("2"), 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。GymCodeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值