码迷,mamicode.com
首页 > 其他好文 > 详细

比赛-模拟赛 (Aug 18, 2018)

时间:2018-08-18 14:52:40      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:typename   priority   int   void   想法   back   empty   集合   clu   

1.) 小X的质数

线性筛就可以了。由唯一分解定理,如果 $ x = p_a \cdot p_b $ ,那么 \(x\) 也一定只能这样分解质因数。所以 \(x\) 也是符合题目条件的数。

#include <cstdio>
#include <ctype.h>
#include <stack>

using namespace std;

template<typename T>
void rd(T &num)
{
    char tt;
    while (!isdigit(tt = getchar()));
    num = tt - '0';
    while (isdigit(tt = getchar()))
        num = num * 10 + tt - '0';
    return;
}

template<typename T>
void pt(T num)
{
    stack<char> S;
    do S.push(num % 10 + '0');
    while (num /= 10);
    while (!S.empty())
        putchar(S.top()), S.pop();
    putchar('\n');
    return;
}

const int _N = 10002000;

int P[_N], sum[_N], Pcnt;
bool mk[_N], mk2[_N];

int main()
{
    
    int N = 10001000, T;
    mk[1] = 1;
    for (int i = 2; i <= N; ++i) {
        if (!mk[i]) P[++Pcnt] = i;
        for (int j = 1; j <= Pcnt && i * P[j] <= N; ++j) {
            mk[i * P[j]] = 1;
            if (!mk[i]) mk2[i * P[j]] = 1;
            if (i % P[j] == 0) break;
        }
        sum[i] = sum[i - 1];
        if (!mk[i] || mk2[i]) ++sum[i];
    }
    rd(T);
    while (T--) {
        int l, r;
        rd(l), rd(r);
        pt(sum[r] - sum[l - 1]);
    }
    return 0;
}

2.) 小X的密室

\(dis_{S, i}\) 表示以 \(S\) 集合的钥匙到达 \(i\) 点的最小消耗。跑最短路或者 BFS (因为边权都是 1 ,所以 BFS 其实比最短路更快)都行。改悔一下,考试的时候输入写错了……输入写错了……输入写错了……

#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <ctype.h>

using namespace std;

template<typename T>
void rd(T &num)
{
    char tt;
    while (!isdigit(tt = getchar()));
    num = tt - '0';
    while (isdigit(tt = getchar()))
        num = num * 10 + tt - '0';
    return;
}

const int _N = 8000;
const int INF = 1e9;

struct data {
    int v, s, w;
    data(int v = 0, int s = 0, int w = 0):
        v(v), s(s), w(w) { }
    bool operator < (const data &tmp)
    const
    {
        return w > tmp.w;
    }
};

struct edge {
    int v, s;
    edge(int v = 0, int s = 0):
        v(v), s(s) { }
};

vector<edge> G[_N];
priority_queue<data> Q;
int N, K, M, dis[_N][3000], A[_N];

void dijkstra(int beg1, int beg2)
{
    while (!Q.empty()) Q.pop();
    for (int i = 1; i <= N; ++i)
        for (int j = 0; j != (1 << K); ++j)
            dis[i][j] = INF;
    dis[beg1][beg2] = 0;
    Q.push(data(beg1, beg2, 0));//v S w
    while (!Q.empty()) {
        data p = Q.top();
        Q.pop();
        if (p.w > dis[p.v][p.s]) continue;
        for (int i = G[p.v].size() - 1; i >= 0; --i) {
            edge e = G[p.v][i];
            if ((p.s & e.s) == e.s) {
                if (dis[e.v][A[e.v] | p.s] > dis[p.v][p.s] + 1) {
                    dis[e.v][A[e.v] | p.s] = dis[p.v][p.s] + 1;
                    Q.push(data(e.v, A[e.v] | p.s, dis[e.v][A[e.v] | p.s]));
                }
            }
        }
    }
    return;
}

int main()
{
    
    rd(N), rd(M), rd(K);
    for (int i = 1; i <= N; ++i)
        for (int j = 0; j < K; ++j) {
            int t;
            rd(t);
            if (t) A[i] |= 1 << j;
        }
    for (int i = 1; i <= M; ++i) {
        int x, y, s = 0;
        rd(x), rd(y);
        for (int j = 0; j < K; ++j) {
            int t;
            rd(t);
            if (t) s |= 1 << j;
        }
        G[x].push_back(edge(y, s));
    }
    dijkstra(1, A[1]);
    int ans = INF;
    for (int i = 0; i != (1 << K); ++i)
        ans = min(ans, dis[N][i]);
    if (ans < INF)
        printf("%d\n", ans);
    else
        printf("No Solution\n");
    return 0;
}

3.) 士兵训练

分析略恶心。首先,分析可得答案是子树内点权的严格次大值。然后考虑外部点权的“加成”。需要维护 \(p\) 为根的子树内的 \(a \geq b > c\) ,以及子树外的 \(x > y\)。然后如果 \(b + x \ne a\) ,直接更新答案就可以。否则答案应为 \(max(b + y, c + x)\) 。然后考虑怎么维护。
法一:最直观的想法是通过节点的 dfn 序重新编号,然后用一颗线段树维护子树内节点。再用前缀、后缀之类的方法维护子树外节点(重新编号后子树外的节点肯定就是 \([1, x]\)\([y, n]\))。
法二:还是用前缀、后缀维护子树外节点,不过直接用子树内节点信息更新子树的答案。
维护前 \(k\) 大的正解是树套树,但是显然用不上,直接 \(O(k^2)\) 暴力合并两个区间(法二中是多个子树,所以两两合并即可)即可(暴力维护前k大方法)。

假装这是代码

比赛-模拟赛 (Aug 18, 2018)

标签:typename   priority   int   void   想法   back   empty   集合   clu   

原文地址:https://www.cnblogs.com/ghcred/p/9497221.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!