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

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大方法)。

假装这是代码

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

时间: 2024-07-30 14:00:35

比赛-模拟赛 (Aug 18, 2018)的相关文章

比赛-CioCio的训练赛 (Aug 18, 2018)

1.) wjj 的子集序列 暴力二进制枚举子集打表,然后可以发现答案就是最大值.根据公式推一波也行吧-- #include <cstdio> #include <stack> #include <ctype.h> using namespace std; typedef long long ll; template<typename T> void rd(T &num) { char tt; bool flag = 0; while (!isdigi

比赛-thh学长的训练赛 (Aug 16, 2018)

1.) 欧拉回路 打表找规律,打了斯特林,打了组合数,找不出,弃疗.我太蠢了,这题和前面这些东西没什么关系啊.考虑 \(n\) 个点时的完全图 \(n \cdot (n - 1) / 2\) 条边,每条边选与不选两种决策,所以可以得到神奇的数字 \(2^{n(n-1)/2}\) ,而答案就是 \(2^{(n-1)(n-2)/2}\) .具体证的话,对于 \(n\) 个点的图,拿出一个点,把 \(n-1\) 个点胡乱连边,方案数 \(2^{(n-1)(n-2)/2}\) .然后让单独拿出来的点与其

模拟赛小结:2018 China Collegiate Programming Contest Final (CCPC-Final 2018)

比赛链接:传送门 跌跌撞撞6题摸银. 封榜后两题,把手上的题做完了还算舒服.就是罚时有点高. 开出了一道奇奇怪怪的题(K),然后ccpcf银应该比区域赛银要难吧,反正很开心qwq. Problem A. Mischievous Problem Setter 00:14 (-2) Solved by Dancepted 良心签到题.WA2吃乳猪. 代码: #include <iostream> #include <cmath> #include <map> #includ

2018 蓝桥杯省赛 B 组模拟赛(一)

2018 蓝桥杯省赛 B 组模拟赛(一) A.今天蒜头君带着花椰妹和朋友们一起聚会,当朋友们问起年龄的时候,蒜头君打了一个哑谜(毕竟年龄是女孩子的隐私)说:“我的年龄是花椰妹年龄个位数和十位数之和的二倍”. 花椰妹看大家一脸懵逼,就知道大家也不知道蒜头君的年龄,便连忙补充道:“我的年龄是蒜头君个位数和十位数之和的三倍”. 请你计算:蒜头君和花椰妹年龄一共有多少种可能情况? 提醒:两位的年龄都是在 [10,100)[10,100) 这个区间内. 题解: 暴力枚举 answer: 1 代码如下: #

2018/5/24模拟赛总结

shzr带病AK虐爆全场... T1n皇后: 这题没啥好说的... T2有重复元素的排列问题: [问题描述] 设R={ r1, r2 , -, rn}是要进行排列的n个元素.其中元素r1, r2 , -, rn可能相同.试设计一个算法,列出R的所有不同排列. [编程任务] 给定n 以及待排列的n 个元素.计算出这n 个元素的所有不同排列. [输入格式] 由perm.in输入数据.文件的第1 行是元素个数n,1≤n≤500.接下来的1 行是待排列的n个元素. [输出格式] 计算出的n个元素的所有不

【2018.11.22】ctsc2018(模拟赛!)

太蠢了……$noip$ 后第一次模拟赛竟然是这样的……完全就是打击自信 / 降智…… 1. 假面 一道神仙概率 $dp$!第一次写…… 拿到题就发现血量 $m_i$ 的上限只有 $100$! 然后 $0$ 操作就可以用 $rate(i,j)$ 动态维护第 $i$ 个人血量为 $j$ 的概率啦. $1$ 操作比较麻烦(但是它故意弄得很少). 设 $live_i$ 和 $dead_i$ 分别为 $1$ 操作范围内的第 $i$ 个人活着和死了的概率,$g_{i,j}$ 是除 $i$ 以外有 $j$ 个

9.2模拟赛

cogs 比赛名称 树立信心的模拟赛 T1 2739. 凯伦和咖啡 时间限制:1 s   内存限制:512 MB [题目描述] 为了在上课时保持清醒,凯伦需要一些咖啡.咖啡爱好者凯伦想知道最佳的温度来冲煮完美的咖啡.因此,她花了一些时间阅读几本食谱,其中包括广受好评的"咖啡的艺术". 她知道有n个食谱,其中第i个食谱建议应当在li和ri度之间冲煮以达到最佳的味道.凯伦认为如果至少k个食谱推荐某个温度,那么那个温度是可以接受的. 凯伦的性格比较多变,因此她会问q个问题,对于每一个问题,她

2019浙大计算机考研机试模拟赛(2)——概念专题

题目链接   引用自晴神OJ A - 边覆盖 B - 极大独立集 C - 稳定婚姻问题 D - 笛卡尔树 没赶得上全程的比赛,就做了两道,后面两道以后有时间再补.两道都是概念题,比较基础~ 以下是题解 A - 边覆盖 Case Time Limit: 200 MS (Others) / 400 MS (Java)       Case Memory Limit: 256 MB (Others) / 512 MB (Java) Accepted: 199      Total Submission

【BZOJ】【2741】【FOTILE模拟赛】L

可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成[某个区间中 max(两个数的异或和)] 要是我们能将所有[l,r]的答案都预处理出来,那么我们就可以O(1)回答了:然而我们并不能. 一个常见的折中方案:分块! 这里先假设我们实现了一个神奇的函数ask(l,r,x),可以帮我们求出[l,r]这个区间中的数,与x最大的异或值. 我们不预处理所有的左端点,我