玲珑杯 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序+线段树)的主要内容,如果未能解决你的问题,请参考以下文章