玲珑杯 1072 - Capture(DFS序+线段树)

Posted AC_Arthur

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玲珑杯 1072 - Capture(DFS序+线段树)相关的知识,希望对你有一定的参考价值。

题目链接:点击打开链接

思路:

不难发现, 这是一棵树, 把树先建立好, 跑dfs序, 然后就变成了线段树区间修改、单点修改、区间最值。

细节参见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <ctime>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef long double ld;
const double eps = 1e-6;
const double PI = acos(-1);
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
// & 0x7FFFFFFF
const int seed = 131;
const ll INF64 = ll(1e18);
const int maxn = 3e5 + 10;
int T, n, cnt_id = 0, dist[maxn];
vector<int> g[maxn];
char s[maxn];
struct node 
    char c;
    int v;
a[maxn];
int tot;
void init() 
    cnt_id = 0;
    tot = 0;
    for(int i = 1; i <= n; i++) g[i].clear(), dist[i] = 0;

void cal() 
    int len = strlen(s);
    ++cnt_id;
    if(s[0] == '+') a[cnt_id].c = '+';
    else a[cnt_id].c = '-';
    a[cnt_id].v = 0;
    for(int i = 1; i < len; i++) 
        a[cnt_id].v = a[cnt_id].v * 10 + s[i]-'0';
    

struct que 
    int id, v;
    que(int id=0, int v=0):id(id),v(v) 
maxv[maxn<<2];
int setv[maxn<<2];
que tal(que a, que b) 
    if(a.v < b.v) return b;
    else if(a.v == b.v) 
        if(a.id < b.id) return a;
        else return b;
    
    else return a;

void pushup(int o) 
    maxv[o] = maxv[o<<1];
    if(maxv[o].v < maxv[o<<1|1].v) maxv[o] = maxv[o<<1|1];
    else if(maxv[o].v == maxv[o<<1|1].v && maxv[o].id > maxv[o<<1|1].id) maxv[o] = maxv[o<<1|1];

void pushdown(int l, int r, int o) 
    if(setv[o] != -1) 
        setv[o<<1] = setv[o<<1|1] = setv[o];
        maxv[o<<1] = maxv[o<<1|1] = que(INF, setv[o]);
        setv[o] = -1;
    

void build(int l, int r, int o) 
    maxv[o] = que(1, 0);
    setv[o] = -1;
    if(l == r) return ;
    int mid = (l + r) >> 1;
    build(l, mid, o<<1);
    build(mid+1, r, o<<1|1);

void update(int L, int R, int id, int v, int l, int r, int o) 
    if(L <= l && r <= R) 
        maxv[o] = que(id, v);
        if(l != r) setv[o] = v;
        return ;
    
    int mid = (l + r) >> 1;
    pushdown(l, r, o);
    if(L <= mid) update(L, R, id, v, l, mid, o<<1);
    if(mid < R) update(L, R, id, v, mid+1, r, o<<1|1);
    pushup(o);

que query(int L, int R, int l, int r, int o) 
    if(L <= l && r <= R) 
        return maxv[o];
    
    int mid = (l + r) >> 1;
    pushdown(l, r, o);
    if(mid >= R) return query(L, R, l, mid, o<<1);
    else if(L > mid) return query(L, R, mid+1, r, o<<1|1);
    else 
        que cur1 = query(L, R, l, mid, o<<1);
        que cur2 = query(L, R, mid+1, r, o<<1|1);
        return tal(cur1, cur2);
    
    pushup(o);

int in[maxn], out[maxn];
void dfs(int u, int fa) 
    in[u] = ++tot;
    int len = g[u].size();
    for(int i = 0; i < len; i++) 
        int v = g[u][i];
        dfs(v, u);
    
    out[u] = tot;

int main() 
    scanf("%d",&T);
    while(T--) 
        scanf("%d", &n);
        init();
        int cnt_node = 1;
        for(int i = 1; i <= n; i++) 
            scanf("%s", s);
            cal();
            if(a[cnt_id].c == '+') 
                int v = a[cnt_id].v;
                g[v].push_back(++cnt_node);
            
        
        dfs(1, 0);
        build(1, cnt_node, 1);
        int cc = 1;
        for(int i = 1; i <= n; i++) 
            if(a[i].c == '+') 
                ++cc;
                int v = a[i].v;
                dist[cc] = dist[v]+1;
                update(in[cc], in[cc], cc, dist[v]+1, 1, cnt_node, 1);
            
            else 
                int v = a[i].v;
                update(in[v], out[v], INF, -INF, 1, cnt_node, 1);
            
            que ans = query(in[1], out[1], 1, cnt_node, 1);
            printf("%d\\n", ans.id);
        
    
    return 0;


以上是关于玲珑杯 1072 - Capture(DFS序+线段树)的主要内容,如果未能解决你的问题,请参考以下文章

“玲珑杯”ACM比赛 Round #18

玲珑杯#7 1/5

“玲珑杯”线上赛 Round #17 河南专场

“玲珑杯”算法比赛 Round #14题目与标程

“玲珑杯”ACM比赛 Round #19

2016-12-24玲珑杯