[10.5模拟赛]T1

T1

Description

在\(2019\)年,某小朋友刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为\(1\)),有以下两种操作:
标记操作:对某个结点打上标记(在最开始,只有结点\(1\)有标记,其他结点均无标记,而且对于某个结点,可以打多次标记。)
询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖先)
你能帮帮他吗?

Input

输入第一行两个正整数\(N\)和\(Q\)分别表示节点个数和操作次数
接下来\(N-1\)行,每行两个正整数\(u\),\(v(1≤u\),\(v≤n)\)表示\(u\)到\(v\)有一条有向边
接下来\(Q\)行,形如“\(oper num\)”\(oper\)为“\(C\)”时表示这是一个标记操作,\(oper\)为“\(Q\)”时表示这是一个询问操作对于每次询问操作。

Output

对于每个询问,输出一个正整数,表示结果。

Sample Input

5 5
1 2
1 3
2 4
2 5
Q 2
C 2
Q 2
Q 5
Q 3

Sample Output

1
2
2
1

Data Constraint

$30%的数据,\(1?N,Q?1000\)
\(70\)%的数据,\(1?N,Q?10000\)
\(100\)%的数据,\(1?N,Q?100000\)

Solution

Code

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 800010
struct rec {
    int nxt, ver;
} t[MAXN];
struct Rec {
    int val;
} tree[MAXN];
int n, q, cnt, u, v, x, s;
int head[MAXN], Top[MAXN], Fa[MAXN], h[MAXN], H[MAXN];
char ch;
bool vis[MAXN];
inline int read() {
    int s = 0, w = 1;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    return s * w;
}
inline void add(int u, int v) {
    t[++cnt].nxt = head[u], t[cnt].ver = v, head[u] = cnt;
}
void DFS(int u, int fa) {
    vis[u] = true, Top[u] = fa, h[u] = ++s, H[s] = u;
    for (register int i = head[u]; i; i = t[i].nxt) {
        int v = t[i].ver;
        if (!vis[v])
            Fa[v] = u, DFS(v, fa);
        break;
    }
    for (register int i = head[u]; i; i = t[i].nxt) {
        int v = t[i].ver;
        if (!vis[v])
            Fa[v] = u, DFS(v, v);
    }
}
inline void update(int now) {
    tree[now].val = max(tree[now << 1].val, tree[now << 1 | 1].val);
}
void Modify(int now, int l, int r, int k) {
    #define mid ((l + r) >> 1)
    if (l == r) {
        tree[now].val = max(tree[now].val, k);
        return;
    }
    if (k <= mid) Modify(now << 1, l, mid, k);
    else Modify(now << 1 | 1, mid + 1, r, k);
    update(now);
    #undef mid
}
int Query(int now, int l, int r, int x, int y) {
    int ans = 0;
    #define mid ((l + r) >> 1)
    if (x <= l && r <= y)
        return max(ans, tree[now].val);
    if (x <= mid) ans = max(ans, Query(now << 1, l, mid, x, y));
    if (mid < y) ans = max(ans, Query(now << 1 | 1, mid + 1, r, x, y));
    return ans;
    #undef mid
}
int fuck(int now) {
    while (now) {
        s = Query(1, 1, n, h[Top[now]], h[now]);
        if (s) return H[s];
        now = Fa[Top[now]];
    }
}
int main() {
    freopen("pa.in", "r", stdin);
    freopen("pa.out", "w", stdout);
    n = read(), q = read();
    for (register int i = 1; i <= n - 1; i++)
        u = read(), v = read(), add(u, v), add(v, u);
    DFS(1, 1);
    Modify(1, 1, n, 1);
    while (q--) {
        ch = getchar();
        if (ch == 'Q') {
            x = read();
            printf("%d\n", fuck(x));
        }
        if (ch == 'C') {
            x = read();
            Modify(1, 1, n, h[x]);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Agakiss/p/11624353.html

时间: 2024-08-29 02:13:02

[10.5模拟赛]T1的相关文章

[10.3模拟赛]T1

Description \(Jim\)是一个胆小的男生,可是每天他都要学习到很晚才能回家,而且他回家的路上没有路灯. \(Jim\)非常怕黑,万幸的是他还有一个手电筒可以用,我们设手电筒的电量上限为\(T\). 在\(Jim\)回家的路上有\((N+1)\)个充电站,\(0\)是起点\(N\)是终点,\(Jim\)每走一个单位距离消耗\(1\)个单位的电量. 给出每个充电站到下一个充电站的距离\(D\),以及冲单位电量的花费\(P\),求整个旅途的最少花费. 如果\(Jim\)无法保证全程手电筒

10.22 模拟赛

10.22 模拟赛 T1 染色 考虑每个连通块删成一棵树就好了. mmp场上就我路径压缩写炸.... #include<iostream> #define MAXN 200006 using namespace std; int n , m; int fa[MAXN] , siz[MAXN] , book[MAXN] , sz[MAXN]; int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } int main() {

10.2模拟赛总结

10.2 模拟赛总结 T1. 数位dp: 一个非常非常非常非常显然的数位 DP \([L,R] = [1,R]-[1,L-1]\) 所以是分别求两次小于等于某个数字的方案数 \(f(i,j,k)\) 表示从低位数起的第 \(i\) 位,按照规则计算后答案为 \(j\quad (j=0,1)\) \(k\) 表示只考虑后面结尾和 \(lmt\)后面几位 的大小关系 \((k=0,1)\) 考虑第 \(i+1\) 位,算一下新构成的数字并判断下大小就可以了 注意到 \(L,R\) 数据范围特别大,需

10.31 模拟赛

10.31 模拟赛 A LIS 考虑每个数字前从 $ m $ 降序构造到 $ a_i $ 即可. #include <iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> using namespace std; #define MAXN 300006 int n , m , k; int A[MAXN]; vector<int&g

10.5模拟赛

这么多模拟赛都没整理,能整理一天算一天吧qaq T1题面 sol:应该不难吧,分别对横坐标和纵坐标取差的绝对值,易知:如果互质就可以看到,否则就不行.然后出题人很毒瘤要用unsigned long long. #include <cstdio> #include <algorithm> using namespace std; long long x1,y1,x2,y2,c1=0,c2=0; unsigned long long x,y; unsigned long long AB

10 01模拟赛订正

好吧,这是我第一次写模拟赛的订正,主要是有时间而且这次的题确实好... 第一题确实好,用的算法人人都会,就是看你能不能想到,我考只打了O(n^4)的暴力,最后还苦逼的MLE,爆零了... 暴力就不多说了...枚举两个点更新其他的点... 其实我考场上思考的是,能被标记的点都与其他的点有什么联系,可惜,除了模拟题目的做法,就不会了... 那让我们就认真地思考一发:我们设A(x1,x2),B(x2,c2),C(x3,c3)来更新D点,只有:有两个点横坐标相等,有两个点纵坐标相等,才可以更新出来一个新

20180610模拟赛T1——脱离地牢

Description 在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活.他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要把它们溶化,Satan就能吸收其精华大增自己的魔力.于是有一天他趁二人不留意,把他们带到了自己的地牢,分别困在了不同的地方.然后Satan念起了咒语,准备炼狱,界时二人都将葬身于这地牢里. 危险!Paris与Helen都知道了Satan的意图,他们要怎样才能打败魔王,脱离地牢呢?Paris想起了父王

[11.10模拟赛]T1

Description 小\(W\)终于学会了魔术, 她迫不及待的想要给你展示一下,小\(W\)的魔术是这样的: 她可以删去一个字符串的任意一个连续子串(可以为空) , 然后把剩下的部分按顺序拼接成一个字符串. 小\(W\)由于刚刚学会魔术, 她只能使用一次. 小\(W\)还有一个特别喜欢的字符串\(s\),如果使用一次魔术之后剩下的字符串就是\(s\),小\(W\)就会对自己的魔术感到满意,但是并不是所有字符串可能让小\(W\)感到满意. 小\(W\)想知道长度为\(n\)的只由小写字母组成的

10.1 模拟赛

由于算错了inf 又ak失败了 过于菜 T1 年轮蛋糕 loj 2758 题目大意: n个数构成的环 把这个环分成三段 使最小的最大 求这个最小段的和的最大值 思路: 可以想到二分 因为log方可以过 所以可以二分长度后lower_bound找断点 或者使用滑动窗口 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cma