关于本次hg模拟赛,题目来源于CF1110。

t1-无意义运算符(meaning)

题目描述

最大公约数和位运算之间有共同点吗?是时候来研究一下了。
给定一个正整数a,请找到一个闭区间[1,a-1] 内的某个整数b,使得a xor b 和a&b 的
最大公约数最大。换句话说,你要求出下面的函数:
\[f(a)=max(gcd(a \ xor \ b, a \ and \ b))(0<b<a)\]
其中\(xor\)表示按位异或,\(and\)表示按位与。

解法

笨蛋chh没有想到正解,就打表发现了规律。

ac代码

看看我冗长的垃圾代码。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ms(a, b) memset(a, b, sizeof(a))
#define LL long long
using namespace std;
inline LL gll() {
    int w = 0, x = 0;
    char ch = 0;
    while (!isdigit(ch)) w |= ch == '-', ch = getchar();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    return w ? -x : x;
}
LL n;
LL gcd(LL n, LL m) {
    return (m == 0) ?(n):(gcd(m, n % m));
}
LL solve(LL x) {
    if (x == 3) return 1;
    if (x == 7) return 1;
    if (x == 15) return 5;
    if (x == 31) return 1;
    if (x == 63) return 21;
    if (x == 127) return 1;
    if (x == 255) return 85;
    if (x == 511) return 73;
    if (x == 1023) return 341;
    if (x == 2047) return 89;
    if (x == 4095) return 1365;
    if (x == 8191) return 1;
    if (x == 16383) return 5461;
    if (x == 32767) return 4681;
    if (x == 65535) return 21845;
    if (x == 131071) return 1;
    if (x == 262143) return 87381;
    if (x == 524287) return 1;
    if (x == 1048575) return 349525;
    if (x == 2097151) return 299593;
    if (x == 4194303) return 1398101;
    if (x == 8388607) return 178481;
    if (x == 16777215) return 5592405;
    if (x == 33554431) return 1082401;
    if (x == 67108863) return 22369621;
    return 1;
}
int main() {
    freopen("meaning.in","r",stdin);
    freopen("meaning.out","w",stdout);
    int cas = gll();
    for (int _t = 1; _t <= cas; _t ++) {
        n = gll();
        LL ans = 1;
        while (ans - 1 < n) ans *= 2; ans -= 1;
        if (ans == n) printf("%lld\n",solve(n));
        else printf("%lld\n", ans);
    }
    return 0;
}

t2-麻将(jongmah)

题目描述

考虑一个变形的麻将游戏:你手头有一副包含n 个牌的麻将牌,每个牌上标有1 到m
的整数。
为了赢得麻将游戏,你必须将所有牌都组成一幅幅的“三张牌”,每一幅“三张牌”的
面值必须是连续的或相等的。如7; 7; 7 和12; 13; 14 都是一幅有效的“三张牌”,而2; 2; 3 和
2; 4; 6 都是无效的。
你想知道,对你手中的这幅麻将牌而言,离胡牌还有多远?也即,对于你手中的牌而言,
最多能凑出多少副“三张牌”?

解法

考试的时候,dp乱搞40分,我隔壁的慕容宝宝大佬模拟还是比我高,自闭ing。

ac代码

#include <bits/stdc++.h>
#define ms(a, b) memset(a, b, sizeof(a))
#define LL long long
using namespace std;
inline int gi() {
    int w = 0, x = 0;
    char ch = 0;
    while (!isdigit(ch)) w |= ch == '-', ch = getchar();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    return w ? -x : x;
}
#define N 1000005
int n, m;
int f[N][5][5], sum[N];
int main() {
    n = gi(), m = gi();
    ms(f, -1);
    f[0][0][0] = 0;
    for (int i = 1; i <= n; i ++) sum[gi()] ++;
    for (int i = 1; i <= m; i ++) {
        for (int j = 0; j < 3 ; j ++) {
            for (int k = 0 ; k <3 ; k ++) {
                for (int l = 0; l < 3; l ++)
                    if (sum[i] < j + k + l) continue;
                    else f[i][k][l] = max(f[i][k][l], f[i - 1][j][k] + (sum[i] - j - k - l) / 3 + l);
            }
        }
    }
    printf("%d\n",f[m][0][0]);
    return 0;
}

t3-魔法石(magic)

题目描述

Grigory 有n 块魔法石,连续编号成1 到n,第i 块魔法石的魔法能量是ci。
有一天Grigory 很无聊,他选择了一块内部(所谓内部就是指编号是2..n-1的)魔
法石,然后对和它相邻的魔法石进行了同步操作。同步后,那块魔法石就丢失了自己的魔法
能量,同时也获得了相邻魔法石的能量。也就是说,如果选中的魔法石的能量是ci,同步后
就变成了c'[i]=c[i+1]+c[i-1]-c[i] .
Grigory 的好朋友Andrew 也有n 块魔法石,他第i 块魔法石的魔法能量是ti。Grigory
很好奇得想知道他的这些魔法石是否可以通过零次或多次同步操作将其魔法能量转换成
Andrew 的对应的魔法石的能量值?也就是说,对于任意的i,是否可以将ci 变成ti?

分析

考试乱搞满分,吐槽数据太水,正解是差分数组排序。

ac代码

#include <bits/stdc++.h>
#define ms(a, b) memset(a, b, sizeof(a))
#define LL long long
using namespace std;
inline int gi() {
    int w = 0, x = 0;
    char ch = 0;
    while (!isdigit(ch)) w |= ch == '-', ch = getchar();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    return w ? -x : x;
}
#define N 100005
int n;
int a[N], b[N], c[N], d[N];
int main() {
    n = gi();
    for (int i = 1; i <= n; i ++) a[i] = gi();
    for (int i = 1; i <= n; i ++) b[i] = gi();
    if (a[1]!=b[1]||a[n]!=b[n]) {
        printf("No\n");
        return 0;
    }
    for (int i = 2; i <= n; i ++) {
        c[i - 1] = a[i] - a[i - 1];
        d[i - 1] = b[i] - b[i - 1];
    }
    sort(c + 1, c + n);
    sort(d + 1, d + n);
    for (int i = 1; i < n; i ++) {
        if (c[i] != d[i]) {
            printf("No\n");
            return 0;
        }
    }
    printf("Yes\n");
    return 0;
}

t4-最近的叶子(leaf)

题目描述

给你一棵带权有根树,根节点为1,且保证每个点i 的父亲pi < i,其中(pi ; i ) 的边权
为wi。
这棵树有个性质:如果我们DFS 这棵树,对于每个点都递增地枚举儿子节点,每访问
到一个节点就记录其编号,那么得到的序列刚好为1 到n。
现在有q 次询问,每次给出vi ; li ; ri,求从vi 出发到[li ; ri ] 中的其中一个叶子节点的最
短距离(保证[li ; ri ] 中至少有一个叶子节点)。(我题目的格式也不调了,比较懒)

题解

考试暴力70分,还算不错。简单讲一下:因为dfs序是连续的,那么就线段树维护答案,跟树链剖分思想差不多。

ac代码

#include <bits/stdc++.h>
#define LL long long
#define pi pair<LL,LL>
#define pii pair<int,pi>
#define fi first
#define se second
#define inf 9999999999999999
#define N 1000005
using namespace std;
vector<pi>G[N];
vector<pii>q[N];
LL a[N], ans[N], dep[N], st[N << 2], add[N << 2];
int tin[N], tout[N], tot, n, m;
void pushup(int nod) {
    st[nod] = min(st[nod << 1], st[nod << 1|1]);
}
void pushdown(int nod, int l, int r) {
    if (add[nod]) {
        add[nod<<1] += add[nod];
        add[nod<<1|1] += add[nod];
        st[nod<<1] += add[nod];
        st[nod<<1|1] += add[nod];
        add[nod] = 0;
    }
}
void build(int nod, int l, int r) {
    if (l == r) st[nod] = a[l];
    else {
        int mid = (l + r) >> 1;
        build((nod << 1), l, mid);
        build((nod << 1 | 1), mid + 1, r);
        pushup(nod);
    }
}
void update(int nod, int l, int r, int ql, int qr, LL v) {
    if (ql <= l && r <= qr) {
        add[nod] += v;
        st[nod] += v;
        return ;
    }
    pushdown(nod, l, r);
    int mid = (l + r) >> 1;
    if (ql <= mid) update(nod << 1, l, mid, ql, qr, v);
    if (qr > mid) update(nod << 1 | 1, mid + 1, r, ql, qr, v);
    pushup(nod);
}
LL query(int nod, int l, int r, int ql, int qr) {
    if (ql <= l && qr >= r) return st[nod];
    pushdown(nod, l, r);
    int mid = (l + r) >> 1;
    LL res = inf;
    if (ql <= mid) res = min(res, query(nod << 1, l, mid, ql, qr));
    if (qr > mid) res = min(res, query(nod << 1| 1, mid + 1, r, ql, qr));
    return res;
}
void dfs_init(int u) {
    ++tot; assert(tot == u);
    tin[u] = tot;
    if (G[u].size() == 0) a[u] = dep[u];
    else a[u] = inf;
    for (int i = 0; i < (int)G[u].size(); i ++) {
        int v =G[u][i].fi;
        dep[v] = dep[u] + G[u][i].se;
        dfs_init(v);
    }
    tout[u] = tot;
}
void dfs(int u) {
    for (int i = 0; i < (int)q[u].size(); i ++)
        ans[q[u][i].fi] = query(1, 1, n, q[u][i].se.fi, q[u][i].se.se) + dep[u];
    for (int i = 0; i < (int)G[u].size(); i ++) {
        int v = G[u][i].fi;
        update(1, 1, n, tin[v], tout[v], -G[u][i].se * 2);
        dfs(v);
        update(1, 1, n, tin[v], tout[v], G[u][i].se * 2);
    }
}
int main() {
    cin>> n>> m;
    for (int i = 2; i <= n; i ++) {
        int u; LL w;
        scanf("%d%lld", &u, &w);
        G[u].push_back((pi){i, w});
    }
    for (int i = 1; i <= m; i ++) {
        int u, v, w;
        scanf("%d%d%d", &w, &u, &v);
        q[w].push_back((pii){i,(pi){u, v}});
    }
    dfs_init(1);
    build(1, 1, n);
    dfs(1);
    for (int i = 1; i <= m;i ++) {
        printf("%lld\n",ans[i]);
    }
    return 0;
}

[hgoi#2019/3/10]赛后总结的更多相关文章

  1. [hgoi#2019/3/3]赛后总结

    T1--最长公共前缀(lcp) 定义两个字符串S,T 的最长公共前缀lcp(S,T)为最长的字符串R,满足R 既是S 的前缀又是T 的前缀. 给定一个字符串S,下标从1 开始,每次询问给出四个正整数a ...

  2. Java学习之JDBC 2019/3/10

    Java学习之JDBC 大部分的程序都是用来通过处理数据来达到人们预期的效果,数据是粮食,没有数据操作的程序就像helloworld程序一样没有用处.因此数据库操作是重中之重,是程序发挥功能的基石,j ...

  3. SPSS 2019年10月24日 今日学习总结

    2019年10月24日今日课上内容1.SPSS掌握基于键值的一对多合并2.掌握重构数据3.掌握汇总功能 内容: 1.基于键值的一对多合并 合并文件 添加变量 合并方法:基于键值的一对多合并 变量 2. ...

  4. 终端、mac等小技巧——2019年10月18日

    1.新建finder窗口 cmd+N 2.查看文件夹结构 brew install tree tree命令行参数(只实用与安装了tree命令行工具): -a 显示所有文件和目录. -A 使用ASNI绘 ...

  5. mac文本操作小技巧——2019年10月17日

    声明:看的别人博主写的,自己整理的,非原创,只是自用. mac文本操作技巧 官方指导文档:https://support.apple.com/zh-cn/HT201236 1.光标移动 1.1 行首. ...

  6. Linux自用指令——2019年10月23日

    1.ls ls命令是列出目录内容(List Directory Contents)的意思.运行它就是列出文件夹里的内容,可能是文件也可能是文件夹. ls -a 列出目录所有文件,包含以.开始的隐藏文件 ...

  7. Gitbook环境搭建及制作——2019年10月24日

    1.gitbook介绍 GitBook 是一个基于 Node.js 的命令行工具,支持 Markdown 和 AsciiDoc 两种语法格式,可以输出 HTML.PDF.eBook 等格式的电子书.可 ...

  8. Visual Studio 2019 v16.10 和 v16.11 Preview 1 现已推出!

    Visual Studio 2019 v16.10有什么新功能? 我们很高兴地宣布Visual Studio 2019 v16.10 GA 和 v16.11 preview 1发布.此版本使我们的主题 ...

  9. 开机时自动启动的AutoHotkey脚本 2019年10月09日

    ;;; 开机时自动启动的AutoHotkey脚本 2019年10月09日;; http://www.autoahk.com/archives/16600; https://www.cnblogs.co ...

随机推荐

  1. NoSql的三大基石:CAP理论&BASE&最终一致性

    关系型数据库的局限 NoSql出现在关系型数据库之后,主要是为了解决关系型数据库的短板,我们先来看看随着软件行业的发展,关系型数据库面临了哪些挑战: 1.高并发 一个最典型的就是电商网站,例如双11, ...

  2. 使用Python遇到:'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte 问题

    查看你的HTTP头部是否有如下头部信息:"Accept-Encoding": "gzip, deflate" 这条信息代表本地可以接收压缩格式的数据,而服务器在 ...

  3. dp方法论——由矩阵相乘问题学习dp解题思路

    前篇戳:dp入门——由分杆问题认识动态规划 导语 刷过一些算法题,就会十分珍惜“方法论”这种东西.Leetcode上只有题目.讨论和答案,没有方法论.往往答案看起来十分切中要害,但是从看题目到得到思路 ...

  4. Notes of Daily Scrum Meeting(12.25)

    今天在学姐的帮助下,我们终于把网络连接的部分连通了,这对我们是一个很大的鼓舞,也找到了前期 连不通的问题在哪里,这让我们重新有了进行下去的勇气和决心,我们会在最后这几天把前端和后端结合, 做出我们最后 ...

  5. 常见IP端口

    21端口:21端口主要用于FTP(File Transfer Protocol,文件传输协议)服务. 23端口:23端口主要用于Telnet(远程登录)服务,是Internet上普遍采用的登录和仿真程 ...

  6. 转发:Android开发?用C#!!

    转发自 最近偶然在QQ技术群里见到有人提起用C#开发Android,当时我感觉到很诧异:Android不是只能用Java开发吗?何时可以使用C#了?那个群友便告知我:mono. 百度一下吧!搜到了mo ...

  7. Mock.js的简易使用

    一:安装 npm install mockjs --save-dev 二:引入 在src目录下创建mock.js文件,输入以下代码: // 引入mockjs const Mock = require( ...

  8. windows的cmd下的find命令比bash(win10下的Ubuntu的bash)下的grep比较

    同样的一个catalina文件,windows的cmd下的find命令比bash下的grep要慢,windows确实占下风啊

  9. 数组操作方法(包括es5)

    //push(); 定义:可以可向数组的末尾添加一个或更多元素,并返回新的长度. 方法:push(); 语法:数组.push(新元素1,新元素2,....,新元素x) 返回值:把指定的值添加到数组后的 ...

  10. 浏览器的F5和Ctrl+F5

    在浏览器里中,按F5键和按F5同时按住Ctrl键(简称Ctrl+F5),效果是不同,到底两者有什么区别呢? 假如我第一次访问过http://localhost/home,这个网页是个动态网页,每次访问 ...