[10.5模拟赛]T1

Posted agakiss

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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;

以上是关于[10.5模拟赛]T1的主要内容,如果未能解决你的问题,请参考以下文章

[10.5模拟赛]T3

雅礼学习10.5

10.5 noip模拟试题

国庆模拟赛day1水题t1反思

1.28 noip t1难度模拟赛

20180606模拟赛T1——猫鼠游戏