t1-Painting

这道题目比较简单,但是我比较弱就只是写了一个链表合并和区间DP。
别人的贪心吊打我的DP,嘤嘤嘤。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
namespace chhokmah {
#define N 100005
#define M 5005
int a[N], l[M], r[M], pos[N];
int n, m, cnt;
ll sum[M], f[M][M];
ll ans = 0;
ll calc(int cnt) {
    for (int i = 1; i <= cnt; i ++) sum[i] += sum[i - 1];
    for (int i = cnt; i; i --)
        for (int j = i; j <= cnt; j ++)
            f[i][j] = max(f[i][j - 1], f[i + 1][j]) + sum[j] - sum[i - 1];
    return f[1][cnt];
}
void chhokmah() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    for (int i = 1; i <= n; i ++) r[a[i]] = i;
    for (int i = n; i; i --) l[a[i]] = i;
    for (int i = 1; i <= m; i ++) pos[l[i]] = i;
    for (int i = 1; i <= n; i ++) {
        if (pos[i]) {
            int cnt = 0, x = i;
            while (pos[x]) { int y = pos[x]; pos[x] = 0; sum[++ cnt] = r[y] - l[y] + 1; x = r[y] + 1; }
            ans += calc(cnt);
        }
    }
    cout << ans << endl;
} }
int main() { chhokmah::chhokmah(); return 0; }

t2-Path

很显然是一道期望\(DP\)。这一道题目还是\(Bluesky\)大佬教我做的,先%为敬。
考虑到最优的策略,一定是从当前算出期望概率较小的点来更新较大的点。


以下是\(BlueSky\)大佬的题解
考虑是按照最优策略进行移动,如果开放一条边且子节点不会使答案变劣,那么就一定会沿该边走向子节点,否则停留在原地。
假设对于点\(i\),不会使答案变劣的点数为\(degree_i\),那么意味着有\(degree_i\)种可能会移动,有\(m-degree_i\)种可能不移动。设点\(i\)走到\(n\)的期望距离为\(f_i\),则有

\[
\begin{array}{rrcl}
&\large f_i&\large =&\large \frac{\large\sum_{v\in son}f_v+(m-degree_i)f_i}{\large m}+1\\\\
\large \Rightarrow&\large mf_i&\large =&\large \sum_{v\in son}f_v+(m-degree_i)f_i+m\\\\
\large \Rightarrow&\large degree_if_i&\large =&\large \sum_{v\in son}f_v+m\\\\
\large \Rightarrow&\large f_i&\large =&\large \frac{\large\sum_{v\in son}f_v+m}{\large degree_i}\\\\
\end{array}
\]

考虑最优策略:
向期望距离尽可能小的位置移动,不会重复经过同一个位置。
反着考虑,从期望距离最小的位置倒着走,对期望距离较大的位置更新答案(即尚未经过的位置)。因为期望距离由可能转移到的位置决定,所以记下对于一个位置可能向多少个位置转移以及转移到的位置的期望距离和。总体从\(n\)出发以堆优化dijkstra的思路跑一遍即可,\(f_1\)就是所求答案。


窝也没有什么可以补充的。
可以稍微讲一下自己在理解时的一些问题。
Q:为什么公式是\(f_i= \frac{\sum_{v\in son}f_v+(m-degree_i)f_i}{ m}+1\)
A:可以理解成走的期望和不走的期望:
设\(sum[i]\)为\(\sum_{v\in son}f_v\)。
走的概率很明显是\(\frac{degree_i}{m}\),那么走的期望就是\(\frac{sum[i]}{m}\)。
考虑不走的话,一定是原先的期望上\(\times\)不走的概率。
不走的概率是\(\frac{m-degree_i}{m}\)
那么不走的期望就是\(\frac{m-degree_i}{m}\times f_i\)
因为无论走还是不走一定会消耗\(1\)的时间,那么需要\(+1\)。

#include <bits/stdc++.h>
#define eps (1e-10)
#define db double
#define ldb long double
#define N 300005
using namespace std;
namespace chhokmah {
struct edge { int to, nt; } E[N << 1];
int H[N], num[N];
ldb f[N], sum[N];
bool vis[N];
int ecnt, n, m;
void add_edge(int u, int v) { E[++ ecnt] = (edge) {v, H[u]}; H[u] = ecnt; }
class cmp {
public:
    bool operator() (int i, int j) {
        if (fabs(f[i] - f[j]) < eps) return i < j;
        else return f[i] < f[j];
    }
};
set <int, cmp> now;
set <int, cmp> :: iterator it;
void chhokmah() {
    scanf("%d%d", &n, &m);
    for (int i = 1, u, v; i <= m; i ++) scanf("%d%d", &u, &v), add_edge(u, v), add_edge(v, u);
    f[n] = 0; now.insert(n);
    for (int i = 1; i <= n; i ++) {
        if (now.empty()) break;
        it = now.begin(); int u = (*it); vis[u] = 1; now.erase(u);
        for (int e = H[u]; e; e = E[e].nt) {
            int v = E[e].to;
            if (!vis[v]) {
                now.erase(v); num[v] ++;
                sum[v] += f[u];
                f[v] = (sum[v] + m) / num[v];
                now.insert(v);
            }
        }
    }
    printf("%0.10f\n", (db) f[1]);
}
}
int main() { chhokmah::chhokmah(); return 0; }

t3-Tree

毒瘤,做不出来。。。
贴一下标称:

#include <stdlib.h>
#include <string.h>
#include <cstdio>
#include <vector>
#include <algorithm>
#define pb push_back
#define sz(a) ((int) (a).size())
using namespace std;
const int N = (int) 3e5;
vector<int> adj[N], who[N], bad[N], path, relax[N];
int n, u, v, root, ans[N], depth[N], h[N], used[N], value[N], it, tlmx[4 * N], trmx[4 * N];

void update(int t, int l, int r, int x, int y) {
    if (l == r - 1)
        tlmx[t] = y, trmx[t] = y + 1;
    else {
        int m = (l + r) / 2;
        if (x < m) update(t * 2 + 1, l, m, x, y);
        else update(t * 2 + 2, m, r, x, y);
        tlmx[t] = max(tlmx[t * 2 + 1], (m - l) + tlmx[t * 2 + 2]);
        trmx[t] = max(trmx[t * 2 + 2], trmx[t * 2 + 1] + (r - m));
    }
}

int get_right(int t, int l, int r, int who, int k) {
    if ((l > who) || (trmx[t] + who - r <= k)) return -1;
    if (l == r - 1) return l;
    int m = (l + r) / 2;
    int rvalue = get_right(t * 2 + 2, m, r, who, k);
    if (rvalue != -1) return rvalue;
    return get_right(t * 2 + 1, l, m, who, k);
}

void get_left(int t, int l, int r, int x, int k, int &lmx, int &res) {
    if (l >= x + 1) return;
    if (r <= x + 1) {
        if (max(tlmx[t], r - l + lmx) < k) {
            lmx = max(tlmx[t], r - l + lmx);
            return;
        } else if (l == r - 1) {
            res = l;
            return;
        }
    }
    int m = (l + r) / 2;
    get_left(t * 2 + 2, m, r, x, k, lmx, res);
    if (res == -1) get_left(t * 2 + 1, l, m, x, k, lmx, res);
}

void set_value(int depth, int nvalue) {
    update(0, 0, h[root] + 1, depth, nvalue);
    value[depth] = nvalue;
}

void update_answer(int k, int who) {
    int marked = get_right(0, 0, h[root] + 1, who, k), lmx = -1, res = -1;
    if (marked == -1) return;
    get_left(0, 0, h[root] + 1, marked, k, lmx, res);
    if (res == -1) res = 0;
    if (value[res] <= k) relax[path[res]].pb(k);
    else bad[path[res]][k] = max(bad[path[res]][k], lmx + 1);
}

void dfs(int v) {
    path.pb(v);
    int mx_u = -1, pre_mx_u = -1;
    for (int i = 0; i < sz(adj[v]); ++i) {
        int u = adj[v][i];
        if ((mx_u == -1) || (h[mx_u] < h[u])) pre_mx_u = mx_u, mx_u = u;
        else if ((pre_mx_u == -1) || (h[pre_mx_u] < h[u])) pre_mx_u = u;
    }
    bad[v] = vector<int>((pre_mx_u == -1) ? 1 : (1 + h[pre_mx_u]), 0);
    for (int i = 0; i < sz(adj[v]); ++i) {
        int u = adj[v][i];
        set_value(depth[v], (u == mx_u) ? ((pre_mx_u == -1) ? 0 : (h[pre_mx_u] + 1)) : (h[mx_u] + 1));
        dfs(u);
    }
    if (mx_u != -1) {
        who[v].swap(who[mx_u]), ++it;
        for (int i = 0; i < sz(adj[v]); ++i) {
            int u = adj[v][i];
            if (mx_u == u) continue;
            used[h[u] + 1] = it;
            for (int k = 0; k <= h[u]; ++k)
                who[v][k] = min(who[v][k], who[u][k]);
        }
        for (int k = 0, mx = 0; k <= ((pre_mx_u == -1) ? -1 : h[pre_mx_u]); ++k) {
            if (used[k] == it) mx = k;
            set_value(depth[v], max(mx, bad[v][k]));
            update_answer(k, who[v][k]);
        }
    }
    who[v].pb(depth[v]);
    set_value(depth[v], 0);
    relax[v].pb(h[v]);
    for (int i = 0; i < sz(relax[v]); ++i) {
        int k = relax[v][i];
        ans[k]++, who[v][k] = depth[v];
        update_answer(k, depth[v]);
    }
    path.pop_back();
}

void calc_h(int v, int p = -1) {
    for (int i = sz(adj[v]) - 1; i >= 0; --i) {
        int u = adj[v][i];
        if (u == p) {
            swap(adj[v][i], adj[v].back());
            adj[v].pop_back();
        } else {
            depth[u] = depth[v] + 1;
            calc_h(u, v);
            h[v] = max(h[v], h[u] + 1);
        }
    }
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i + 1 < n; ++i) {
        scanf("%d%d", &u, &v), --u, --v;
        adj[u].pb(v), adj[v].pb(u);
    }
    root = 0;
    calc_h(root);
    for (int i = 0; i < n; i ++) cout <<
    dfs(root);
    for (int d = h[root] + 1; d <= n; ++d)
        ans[d] = 1;
    for (int k = 1, d = n; k <= n; ++k) {
        while ((d > 0) && (ans[d - 1] <= k)) --d;
        printf("%d%c", d, " \n"[k == n]);
    }
    return 0;
}

「HGOI#2019.4.19省选模拟赛」赛后总结的更多相关文章

  1. 5.19 省选模拟赛 小B的夏令营 概率 dp 前缀和优化dp

    LINK:小B的夏令营 这道题是以前从没见过的优化dp的方法 不过也在情理之中. 注意读题 千万不要像我这个sb一样 考完连题意都不知道是啥. 一个长方形 要求从上到下联通的概率. 容易发现 K天只是 ...

  2. 5.19 省选模拟赛 小B的图 最小生成树 LCT

    LINK:小B的图 这道题就比较容易了. 容易想到将询问离线 然后 从小到大排序 那么显然是优先放正图(x+k)的边. 考虑随着x的增大 那么负图上的边会逐渐加进来 一条边被加进来当且仅当 其权值小于 ...

  3. 5.19 省选模拟赛 T1 小B的棋盘 双指针 性质

    LINK:小B的棋盘 考试的时候没有认真的思考 导致没做出来. 容易发现 当k>=n的时候存在无限解 其余都存在有限解 对于30分 容易想到暴力枚举 对称中心 然后 n^2判断. 对于前者 容易 ...

  4. 「CSP-S模拟赛」2019第四场

    「CSP-S模拟赛」2019第四场 T1 「JOI 2014 Final」JOI 徽章 题目 考场思考(正解) T2 「JOI 2015 Final」分蛋糕 2 题目 考场思考(正解) T3 「CQO ...

  5. #10470. 「2020-10-02 提高模拟赛」流水线 (line)

    题面:#10470. 「2020-10-02 提高模拟赛」流水线 (line) 题目中的那么多区间的条件让人感觉极其难以维护,而且贪心的做法感觉大多都能 hack 掉,因此考虑寻找一些性质,然后再设计 ...

  6. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  7. #10471. 「2020-10-02 提高模拟赛」灌溉 (water)

    题面:#10471. 「2020-10-02 提高模拟赛」灌溉 (water) 假设只有一组询问,我们可以用二分求解:二分最大距离是多少,然后找到深度最大的结点,并且把它的\(k\)倍祖先的一整子树删 ...

  8. 「NOIP模拟赛」数位和乘积(dp,高精)

    统计方案数,要么组合数,要么递推(dp)了. 这是有模拟赛历史以来爆炸最狠的一次 T1写了正解,也想到开long long,但是开错了地方然后数组开大了结果100->0 T3看错题本来简单模拟又 ...

  9. ZROI 19.08.07模拟赛

    传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. "正睿从来没有保证,模拟赛的题目必须原创." "文案不是我写的,有问题找喵老师去."--蔡老师 ...

随机推荐

  1. 42.Odoo产品分析 (四) – 工具板块(10) – 问卷(2)

    查看Odoo产品分析系列--目录 接上一篇Odoo产品分析 (四) – 工具板块(10) – 问卷(1) 4 页面 即问卷,点开一项查看:  可以看出,网页就是问卷本身的子目录,其中指明了该目录包括哪 ...

  2. installation failed with message INSTALL_FAILED_INSUFFICIENT_STORG

    在安装APK的时候有时候会出现这种错误,原因是卸载之前的APK不彻底,有残余,手动删除android目录下相关的文件.

  3. C# 仿360悬浮球开发demo程序

    https://files.cnblogs.com/files/wohexiaocai/%E4%BB%BF360%E5%8A%A0%E9%80%9F%E5%99%A8.zip

  4. Windbg学习笔记

    下载winsdksetup.exe ,双击,选择Debugging Tools for Windows安装. 64位系统抓64位进程dump,用64位windbg来分析.64位系统抓32位进程dump ...

  5. Oracle 查询权限视图

    在Oracle中有很多用于查权限的视图,但很多人在需要查权限时会很困惑,不知道该用哪个视图去查,这里我列出几个常见的用于查权限的视图及其用法: 1DBA_ROLE_PRIVS 该视图主要有以下2个作用 ...

  6. centos6.5上进行crontab操作

    1.service crond start 2. vi  /home/cron.ini */ * * * * /home/monitor.sh 3.crontab  /home/cron.ini OK

  7. Python 位操作运算符

    & 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100 | 按位或运算符:只要对应的二 ...

  8. requests的基本用法

    r = requests.get('https://api.github.com/events', params = {'key1': 'value1', 'key2': 'value2'}) r = ...

  9. 模块简介:(logging)(re)(subprocess)

    ''' logging模块: logging的日志可以分为 debug():Detailed information, typically of interest only when diagnosi ...

  10. vue中的watch方法 实时同步存储数据

    watch 监视模式里面有个独特的方法handler 注意要加上deep: true.deep为true时,当对象的key值改变时也监听 当值发生改变被watch监视到触发了事件 开始执行handle ...