\(T1\)

题目描述

在仙界中有着 \(n\) 位神仙, 每位神仙用一个 \(1 ∼ n\) 的特异编号表示, 老祖 \(ChitongZ\) 的编号为 \(1\) .

除去至尊至圣, 统管仙界的老祖 \(ChitongZ\) 外, 其他的 \(n − 1\) 位神仙都有唯一的尊师, 并且形成了一个树形结构.

老祖 \(ChitongZ\) 为了提升仙界综合实力, 倡导神仙们进行修炼.

但每次修炼是需要一颗金丹的, 若一位神仙自己没有金丹, 就需要向自己的尊师索取一颗. 若尊师也没有, 则尊师会向他的尊师索取一颗, 以此类推, 直到索取到一颗金丹, 修炼结束后这颗金丹就会被消耗掉.

\(Solution\)

预估 \(100pts\) ,数组开小了只有 \(60pts\)

其实这道题很多做法,我想了两个,都记录一下

\(EP.1\)

类似树剖,先做一个 \(dfs\) ,给每个点标上 \(dfs\) 序 \(id[x]\),用线段树维护覆盖

对于一个点 \(x\) ,离它最近的被标记的点(即 \(ans\))是 所有可以覆盖它的点中 \(id\) 最大的,所以在每次线段树做 \(pushdown\) 的时候取 \(max\) ,输出的时候再转化为原答案

\(EP.2\)

用并查集维护

把所有操作保存下来,构造出一颗树,树的状态为所有操作完成后,再做一个 \(dfs\) ,若点 \(x\) 被标记过,则 \(s[x] = x\) ,不然指向 \(fa[x]\)

然后倒着操作,即给一个点标记变为去掉一个点的标记,若这个点没有标记了,则把 \(s[x]\) 指向 \(fa[x]\)

Code

只有 \(EP.2\) 的代码233

#include<bits/stdc++.h>
#define ll long long
#define F(i, x, y) for(int i = x; i <= y; ++ i)
using namespace std;
int read();
const int N = 5e6 + 5;
const ll B1 = 37;
const ll P1 = 19260817;
const ll B2 = 137;
const ll P2 = 998244353;
int n, m, x;
int s[N], d[N], fa[N], k[N];
ll ans1, ans2;
struct kk{
int edge;
char sta;
}Q[N];
int head[N], cnt;
struct node{
int ver, next;
}a[N << 1];
void add(int x, int y)
{
++ cnt;
a[cnt].ver = y, a[cnt].next = head[x], head[x] = cnt;
}
void dfs(int x, int f)
{
s[x] = d[x] ? x : f, fa[x] = f;
for(int i = head[x]; i; i = a[i].next)
if(a[i].ver != f)
dfs(a[i].ver, x);
}
int search(int x)
{
return x == s[x] ? x : s[x] = search(s[x]);
}
int main()
{
freopen("decomposition.in","r",stdin);
freopen("decomposition.out","w",stdout);
n = read(), m = read();
F(i, 2, n) x = read(), add(x, i), add(i, x);
F(i, 1, m)
{
Q[i].sta = read(), Q[i].edge = read();
if(Q[i].sta == 2) ++ d[Q[i].edge];
}
dfs(1, 0), s[1] = 1, fa[1] = 1;
for(int i = m; i >= 1; -- i)
{
if(Q[i].sta == 1) k[i] = search(Q[i].edge);
else
{
-- d[Q[i].edge];
if(! d[Q[i].edge]) s[Q[i].edge] = fa[Q[i].edge];
}
}
F(i, 1, m) if(k[i])
ans1 = (ans1 * B1 + k[i]) % P1, ans2 = (ans2 * B2 + k[i]) % P2;
printf("%lld %lld", ans1, ans2);
return 0;
}
int read()
{
int x = 0;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x;
}

\(T2\)

题目描述

有 \(n\) 个人依次进入观影厅, 观看 \(Weathering \ with \ You\) .

观影厅只有一排座位, 第 \(1\) 个人进入时, 会选择第 \(1\) 个座位坐下.

由于观影厅空调坏掉了, 十分炎热, 之后的每个人进入时, 他会选择一个离最近的已经坐下的人尽可能远的空位.

如果有多个空位使得离最近的人同样远, 则他会从其中随机选取一个.

若有两个人选择的位置相邻, 他们就会不满意.

为了让所有人都满意, 观影厅至少需要有几个座位呢?

\(Solution\)

根据各种打表找规律可得出

\[f(x) = x + 2^{1+⌊log_2(x−2)⌋}.
\]

然后用高精度写

比较方便的写法是,用 \(2\) 不断往上乘,一边乘一边判断大小,最后加一个 \(n\)

这样就只要写高精乘低精,判断大小,高精度加法,比较好写

还有特殊情况,\(f(1) = 1\) ,\(f(2) = 3\),我没想到然后就只有 \(95pts\)

Code

#include<bits/stdc++.h>
#define F(i, x, y) for(int i = x; i <= y; ++ i)
using namespace std;
int read();
const int N = 2e3 + 5;
char z;
int a[N], alen;
int b[N], blen;
int c[N], clen;
void mul(int b[])
{
int x = 0;
F(i, 1, blen) x += b[i] * 2, b[i] = x % 10, x = x / 10;
if(x) b[++ blen] = x;
}
bool comp(int a[], int b[])
{
int x = 2, clen = blen;
F(i, 1, blen) c[i] = b[i];
F(i, 1, clen)
{
c[i] += x, x = c[i] / 10, c[i] %= 10;
if(! x) break;
}
if(x) c[++ clen] = x;
if(alen != clen) return alen > clen;
for(int i = alen; i >= 1; -- i)
if(a[i] != c[i]) return a[i] > c[i];
return true;
}
int main()
{
freopen("tenki.in","r",stdin);
freopen("tenki.out","w",stdout);
while(scanf("%c", &z) != EOF) c[++ alen] = z - '0';
-- alen;
F(i, 1, alen) a[alen - i + 1] = c[i];
if(alen == 1 && (a[1] == 1 || a[1] == 2))
{
puts(a[1] == 1 ? "1" : "3");
return 0;
}
blen = 1, b[blen] = 2;
while(comp(a, b)) mul(b);
memset(c, 0, sizeof(c));
F(i, 1, max(alen, blen))
{
c[i] = c[i] + a[i] + b[i];
c[i + 1] = c[i] / 10, c[i] %= 10;
}
clen = max(alen, blen);
if(c[clen + 1]) ++ clen;
for(int i = clen; i >= 1; -- i) printf("%d", c[i]);
return 0;
}
/*
q = (log2 (n - 2)) + 1;
ans = 2 ^ q + n;
*/

\(T3\)

题目描述

给定一个正整数 \(k\) , 以及一棵 \(n\) 个节点的以 \(1\) 为根的有根树, 边有长度.

记 \(LCA(a, b)\) 表示 \(a\) 与 \(b\) 在树上的最近公共祖先, \(dist(a)\) 表示树根到 \(a\) 的距离.

每个节点可以是黑色或白色, 初始时每个节点的颜色为白色.

进行 m 次操作, 每次操作是以下两种形式之一:

修改操作: 给出一个修改节点 \(x\) , 将节点 \(x\) 染上黑色. 保证 \(x\) 在染色前为白色.

询问操作: 给出一个询问节点 \(x\) , 记所有黑点形成的集合为 \(S\) , 求出下面式子的值:

\[\sum_{y∈S}F( dist ( LCA ( x, y ) ) )
\]

其中函数 \(F\) 定义为,

\[F(x) =\sum\limits_{i=1}^xi^k
\]

由于答案可能很大, 只需要输出答案对 \(P = 998244353\) 取模的结果

\(Solution\)

这道题的难点:

\(1.\)题意比较绕,要求的答案函数套函数,很容易弄错

\(2.\)列出式子并把式子化简,将定值和要维护的值拆开

肝了半个下午 \(+\) 半个晚自习,心力交瘁...不过真的是道好题!!

\((btw\),膜一膜 \(xiaolilsq\) 大佬,本来我都没信心把这道题改出来233,结果他讲题讲得好清楚然后就改掉了!\()\)

\(Code\)

#include<bits/stdc++.h>
#define ll long long
#define ls k << 1
#define rs (k << 1) + 1
#define mid ((l + r) >> 1)
#define F(i, x, y) for(int i = x; i <= y; ++ i)
using namespace std;
int read();
const int N = 1e5 + 5;
const int M = 1e7 + 5;
const int mod = 998244353;
int n, m, s;
ll x, y, num, vis[N], f[M], dist[N];
ll tree[N << 2], atree[N << 2], tag[N << 2], a[N];
ll dep[N], size[N], fa[N], son[N], id[N], top[N];
ll head[N], cnt, ver[N << 1], edge[N << 1], nxt[N << 1];
void add(int x, int y, int z)
{
ver[++ cnt] = y, edge[cnt] = z, nxt[cnt] = head[x], head[x] = cnt;
}
ll qpower(ll x, int y)
{
ll res = 1;
while(y)
{
if(y & 1) res = res * x % mod;
x = x * x % mod, y >>= 1;
}
return res;
}
void dfs1(int x, int ffa)
{
dep[x] =dep[ffa] + 1, size[x] = 1, fa[x] = ffa;
int maxn = -1;
for(int i = head[x]; i; i = nxt[i])
if(ver[i] != ffa)
{
dist[ver[i]] = dist[x] + edge[i], dfs1(ver[i], x), size[x] += size[ver[i]];
if(size[ver[i]] > maxn) son[x] = ver[i], maxn = size[ver[i]];
}
}
void dfs2(int x, int topfa, int ffa)
{
id[x] = ++ num, top[x] = topfa;
a[id[x]] = (f[dist[x]] - f[dist[ffa]] + mod) % mod;
if(! son[x]) return;
dfs2(son[x], topfa, x);
for(int i = head[x]; i; i = nxt[i])
if(ver[i] != fa[x] && ver[i] != son[x])
dfs2(ver[i], ver[i], x);
}
void pushup(int l, int r, int k)
{
atree[k] = (atree[ls] + atree[rs]) % mod;
}
void build(int l, int r, int k)
{
if(l == r)
{
tree[k] = a[l] % mod;
return;
}
build(l, mid, ls);
build(mid + 1, r, rs);
tree[k] = (tree[ls] + tree[rs]) % mod;
}
void pushdown(int l, int r, int k)
{
if(! tag[k]) return;
atree[ls] = (tree[ls] * tag[k] % mod + atree[ls]) % mod;
atree[rs] = (tree[rs] * tag[k] % mod + atree[rs]) % mod;
tag[ls] += tag[k], tag[rs] += tag[k];
tag[k] = 0;
}
void modify(int l, int r, int k, int x, int y, int v)
{
if(l >= x && r <= y)
{
atree[k] = (tree[k] * v % mod + atree[k]) % mod, tag[k] += v;
return;
}
pushdown(l, r, k);
if(x <= mid) modify(l, mid, ls, x, y, v);
if(y > mid) modify(mid + 1, r, rs, x, y, v);
pushup(l, r, k);
}
ll query(int l, int r, int k, int x, int y)
{
if(l >= x && r <= y) return atree[k];
pushdown(l, r, k);
ll res = 0;
if(x <= mid) res = (res + query(l, mid, ls, x, y)) % mod;
if(y > mid) res = (res + query(mid + 1, r, rs, x, y)) % mod;
return res;
}
void modify_range(int x)
{
if(vis[x]) return;
vis[x] = 1;
while(top[x] != 1)
{
modify(1, n, 1, id[top[x]], id[x], 1);
x = fa[top[x]];
}
modify(1, n, 1, 1, id[x], 1);
}
ll query_range(int x)
{
ll res = 0;
while(top[x] != 1)
{
res = (res + query(1, n, 1, id[top[x]], id[x])) % mod;
x = fa[top[x]];
}
res = (res + query(1, n, 1, 1, id[x])) % mod;
return res;
}
int main()
{
freopen("mafumafu.in","r",stdin);
freopen("mafumafu.out","w",stdout);
n = read(), m = read(), s = read();
F(i, 1, M - 1) f[i] = (f[i - 1] + qpower(i, s) % mod) % mod;
F(i, 2, n) x = read(), y = read(), add(x, i, y), add(i, x, y);
dfs1(1, 0), dfs2(1, 1, 0), build(1, n, 1);
while(m --)
{
y = read(), x = read();
if(y == 1) modify_range(x);
if(y == 2) printf("%lld\n", query_range(x));
}
return 0;
}
int read()
{
int x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}

总结

排名\(:5/17\)

预估分数\(:100 + 100 + 0\)

实际分数\(:60 + 95 + 0\)

\(1.\)都 \(0202\) 了我怎么还犯数组开小了这种错误。。。

\(2.\)都 \(0202\) 了我怎么还反不考虑特殊情况这种错误。。。

总体来说今天还行,调整了考试状态,尽力地拿分,其实写完前两道题后还剩半个小时,打了 \(t3\) 的暴力,可惜没时间调了,不过这种习惯还是要坚持,抓住每一分每一秒;但是还是有一些**错误,爆锤我寄几!!!

【考试总结】欢乐模拟赛_Day2的更多相关文章

  1. 【考试总结】欢乐模拟赛_Day1

    \(T1\) 题目描述 给出一个 \(n × n\) 的, 元素为自然数的矩阵. 这个矩阵有许许多多个子矩阵, 定义它的所有子矩阵形成的集合为 \(S\) . 对于一个矩阵 \(k\) , 定义 \( ...

  2. NOIP欢乐模拟赛 T1 解题报告

    小澳的方阵 (matrix.cpp/c/pas) [题目描述] 小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局. 他努力钻研,发现秦始皇布置兵马俑 ...

  3. NOIP欢乐模拟赛 T3 解题报告

    3.小澳的葫芦 (calabash.cpp/c/pas) [题目描述] 小澳最喜欢的歌曲就是<葫芦娃>. 一日表演唱歌,他尽了洪荒之力,唱响心中圣歌. 随之,小澳进入了葫芦世界. 葫芦世界 ...

  4. NOIP欢乐模拟赛 T2 解题报告

    小澳的坐标系 (coordinate.cpp/c/pas) [题目描述] 小澳者表也,数学者景也,表动则景随矣. 小澳不喜欢数学,可数学却待小澳如初恋,小澳睡觉的时候也不放过. 小澳的梦境中出现了一个 ...

  5. Test20171009 考试总结 NOIP模拟赛

    题目难度合适,区分度适中,但是本人水平不佳,没有拿到满意的分数. T1(matrix) 一种比较容易想到的想法是枚举起点求出最长全1串做预处理,这是O(n^2)的. 接着枚举列起点,列终点,通过后缀和 ...

  6. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  7. PKUSC 模拟赛 day1 下午总结

    下午到了机房之后又困又饿,还要被强行摁着看英文题,简直差评 第一题是NOIP模拟赛的原题,随便模拟就好啦 本人模拟功力太渣不小心打错了个变量,居然调了40多分钟QAQ #include<cstd ...

  8. [GRYZ]寒假模拟赛

    写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...

  9. 10.30 NFLS-NOIP模拟赛 解题报告

    总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...

随机推荐

  1. Alpine Linux 常用命令

    一:Alpine Linux开启SSH远程登陆 1.简介: 最重要的一个服务了,远程登陆需要用它,文件传输需要用它,必备功能.不管你是在实体机上跑,虚拟机上跑,docker里面跑,这个都是必须的. 2 ...

  2. 给rm命令加保险

    众所周知,脑残可以学习,但是手残没法治.相信每一位喜欢用终端操作电脑的同学都曾手误使用 rm 命令把不该删除的文件删了.然而,使用 rm 删除的文件是不会进去回收站的. 所以,最好的方法就是我们自定义 ...

  3. Python终端打印彩色文字

    终端彩色文字 class Color_f: black = 30 red = 31 green = 32 yellow= 33 blue = 34 fuchsia=35 cyan = 36 white ...

  4. 实现ls

    一.任务详情 参考伪代码实现ls的功能,提交代码的编译,运行结果截图,码云代码链接 打开目录文件 针对目录文件 读取目录条目 显示文件名 关闭文件目录文件 二.伪代码 opendir while(re ...

  5. Java是未来的第一编程语言吗?

    目录 一.前言 二.Java帝国的今天 2.1 依然霸占TIOBE热门编程语言的榜首 2.2 曾经想扼杀Java的微软宣布加入OpenJDK 2.3 Oracle发布开源全栈虚拟机GraalVM 三. ...

  6. Java递归练习201908091049

    package org.jimmy.autofactory.test; public class TestRecursive20190809 { public static void main(Str ...

  7. 玩转控件:封装Dev的SearchLookupEdit

    鸣谢 随着前面几个章节对控件封装与扩展的分享,不少小伙伴儿们在作者公众号上反馈,并联系作者,表示通过这些系列和源码能学到不少细节上的东西,并运用到了自己的实际项目当中,也有不少伙伴儿反馈更好更优的处理 ...

  8. U - Inviting Friends HDU - 3244( LIS 最长升序子序列——变形 )

    序列变换 Problem Description 我们有一个数列A1,A2-An,你现在要求修改数量最少的元素,使得这个数列严格递增.其中无论是修改前还是修改后,每个元素都必须是整数. 请输出最少需要 ...

  9. 【原创】Linux RCU原理剖析(一)-初窥门径

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  10. Mysql数据库卸载

    Mysql数据库卸载的操作流程(Windows10): 1.停止mysql的所有服务 方法一:此电脑——管理——服务中查找到所有Mysql的服务,并停止. 方法二:cmd——net stop mysq ...