您的位置:首页 > 产品设计 > UI/UE

Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query (线段树)

2017-11-29 20:47 555 查看
题目链接:http://codeforces.com/contest/893/problem/F

这个题好像挺傻逼的啊?

首先dfs序,然后线段树维护,每个节点维护一个vector表示这个区间中所有的节点的深度,这样的空间复杂度为O(nlogn),因为不涉及修改,咱们的对每个节点的vector都进行排序,然后每次按照区间查询就好了,貌似不用树套树,这个题就很好写了啊?

代码:

#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<assert.h>
#include<iostream>
#define mp make_pair
#define xx first
#define yy second
using namespace std;
const int MAXN = 1e5 + 5;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> pii;
struct edge
{
int v, nxt;
}E[MAXN*2];
struct node
{
vector<pii> sv;
vector<int> mi;
int query(int k)
{
int ret = upper_bound(sv.begin(), sv.end(), mp(k,INF)) - sv.begin();
if (ret == 0)
return INF;
ret--;
return mi[ret];
}
void push(pii k)
{
sv.push_back(k);
}
void Sort()
{
sort(sv.begin(), sv.end());
int tmp = INF;
for (auto i : sv)
{
tmp = min(tmp, i.yy);
//assert(tmp >= 0);
mi.push_back(tmp);
}
}
};
struct seg
{
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
node tr[MAXN << 2];
void update(int pos, pii val, int l, int r, int rt)
{
tr[rt].push(val);
if (l == r)
return;
int mid = (l + r) >> 1;
if (mid >= pos)
update(pos, val, lson);
if (mid < pos)
update(pos, val, rson);
}
int query(int L, int R,int val, int l, int r, int rt)
{
if (L <= l&&r <= R)
return tr[rt].query(val);
int mid = (l + r) >> 1;
int ret = INF;
if (mid >= L)
ret = min(ret, query(L, R, val, lson));
if (mid < R)
ret = min(ret, query(L, R, val, rson));
return ret;
}
void build(int l, int r, int rt)
{
tr[rt].Sort();
if (l == r)
return;
int mid = (l + r) >> 1;
build(lson);
build(rson);
}
}se;
int n, root, q, tot, tim;
int in[MAXN], out[MAXN], dep[MAXN], a[MAXN],head[MAXN];
void addedge(int u, int v)
{
E[tot].v = v;E[tot].nxt = head[u];head[u] = tot++;
E[tot].v = u;E[tot].nxt = head[v];head[v] = tot++;
}
void init()
{
memset(head, -1, sizeof(head));
tot = 0, tim = 0;
}
void dfs(int now, int fa,int dp)
{
in[now] = ++tim;
dep[now] = dp;
se.update(in[now], mp(dp, a[now]), 1, n, 1);
for (int i = head[now];~i;i = E[i].nxt)
{
int v = E[i].v;
if (v == fa)
{
continue;
}
dfs(v, now, dp + 1);
}
out[now] = tim;
}
void solve()
{
int q;
init();
scanf("%d%d", &n, &root);
for (int i = 1;i <= n;i++)
{
scanf("%d", &a[i]);
}
for (int i = 1;i < n;i++)
{
int u, v;
scanf("%d%d",&u,&v);
addedge(u, v);
}
dfs(root, 0, 1);
se.build(1, n, 1);
scanf("%d", &q);
int last = 0;
while (q--)
{
int x, k;
scanf("%d%d", &x, &k);
x = (x + last) % n + 1;k = (k+ last) % n;
printf("%d\n", last=se.query(in[x], out[x], dep[x] + k, 1, n, 1));
}
}
int main()
{
solve();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: