[OJ#40]后宫佳丽

试题描述

如果机房要关门了,或者有妹子在等你,你可以直接看最后一句话。

Fyq 是一只饥渴的鸭子。

Fyq 有一个充实的后宫,可惜他总是体力不支,为此他经常苦恼,总是想方设法让自己能够泡到更多妃子。

Fyq 为他的的每个妃子建立了一间屋子,屋子与屋子之间可能有一条路连接。每条路有一个长度 len,Fyq 走过这条路时会消耗 len 的体力,但是当 Fyq 进入一间屋子云雨一翻后,体力立刻恢复至初始值。每个妃子有一个类型 typei,Fyq 希望知道他见到次数最多的会是哪个类型,以便做更加充分的准♂备。注意,如果有见到次数并列第一的几个类型,那么请输出类型编号最小的,因为 Fyq 更加偏爱类型编号小的妃子。

接下来有 q 天,Fyq 每天都打算找他的妃子们。第 i 天他会从妃子 xi 的屋子出发,初始时有 wi 的体力。你不能让 Fyq 太虚导致他无法好好享受,所以你要保证任何时刻不能让他的体力值低于 0。

一句话题意:给你一个 n 个节点 m 条边的无向图,边有长度,点带颜色(节点 i 的颜色为 typei);给你 q 个询问形如 (xi,wi),每次你从节点 xi 出发,只能走长度不超过 wi 的边,问经过的所有节点中颜色数目最多的颜色是哪个(如果有多个并列,输出颜色编号最小的)。

(无向图有可能不连通。)

输入

第一行三个整数 n,m,secret。secret 的含义待会解释。

第二行 n 个整数,第 i 个整数表示 typei

接下来 m 行每行三个整数 u,v,len,表示 u,v 之间有一条长度为 len 的双向边。

接下来一行一个整数 q。

接下来 q 行,每行两个整数 xi,wi 表示 Fyq 一天的计划。

secret 的值域为 {0,1},若 secret=1 表示 Fyq 比较害羞,他不肯一次告诉你接下来 q 天的所有计划,所以他对计划进行了加密,解密的方式 xi 和 wi 都异或上 lastans,lastans 表示昨天的答案;如果是第一天 lastans=0,即第一天的信息 Fyq 没有加密。

输出

输出 q 行,第 i 行一个整数表示第 i 天的答案。

输入示例1


输出示例1


输入示例2


输出示例2


数据规模及约定

对于 20% 的数据,1≤n≤1000

对于另外 40% 的数据,secret=0

对于全部数据,1≤n≤105,1≤m,q≤2×105,1≤typei,u,v,xi≤n,1≤len,wi≤106

题解

我们构出 kruskal 重构树,问题变成了求子树内最小众数,可以自底向上用平衡树启发式合并算出每个节点的子树的答案。

关于 kruskal 重构树可以去看一下这道题

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 100010
#define maxm 200010
#define maxlog 18 struct Node {
int col, val, r, siz;
Node() {}
Node(int _1, int _2, int _3): col(_1), val(_2), r(_3) {}
bool operator < (const Node& t) const { return val != t.val ? val < t.val : col > t.col; }
} ns[maxn];
int ToT, ch[maxn][2], fa[maxn], rec[maxn], rcnt;
int getnode() {
if(rcnt) {
int o = rec[rcnt--];
ch[o][0] = ch[o][1] = fa[o] = 0;
return o;
}
return ++ToT;
}
void maintain(int o) {
if(!o) return ;
ns[o].siz = ns[ch[o][0]].siz + 1 + ns[ch[o][1]].siz;
return ;
}
void rotate(int u) {
int y = fa[u], z = fa[y], l = 0, r = 1;
if(z) ch[z][ch[z][1]==y] = u;
if(ch[y][1] == u) swap(l, r);
fa[u] = z; fa[y] = u; fa[ch[u][r]] = y;
ch[y][l] = ch[u][r]; ch[u][r] = y;
maintain(y); maintain(u);
return ;
}
Node opt;
void Add(int& o, int col, int val) {
if(!o) {
ns[o = getnode()] = Node(col, val, rand()); opt = max(opt, ns[o]);
return maintain(o);
}
if(ns[o].col == col){ ns[o].val += val; opt = max(opt, ns[o]); return ; }
bool d = col > ns[o].col; opt = max(opt, ns[o]);
Add(ch[o][d], col, val); fa[ch[o][d]] = o;
if(ns[ch[o][d]].r > ns[o].r) {
int t = ch[o][d];
rotate(t); o = t;
}
return maintain(o);
}
Node Set[maxn]; int cnts;
void recycle(int& o) {
if(!o) return ;
Set[++cnts] = ns[o];
rec[++rcnt] = o;
recycle(ch[o][0]); recycle(ch[o][1]);
o = 0;
return ;
} struct Edge {
int a, b, c;
Edge() {}
Edge(int _1, int _2, int _3): a(_1), b(_2), c(_3) {}
bool operator < (const Edge& t) const { return c < t.c; }
} es[maxm]; int pa[maxn<<1], Rt[maxn<<1];
int findset(int x){ return x == pa[x] ? x : pa[x] = findset(pa[x]); } int E, head[maxn<<1], nxt[maxn<<1], to[maxn<<1], Fa[maxn<<1][maxlog];
void AddEdge(int a, int b) {
to[++E] = b; nxt[E] = head[a]; head[a] = E;
return ;
}
bool vis[maxn<<1];
void build(int u) {
vis[u] = 1;
for(int i = 1; i < maxlog; i++) Fa[u][i] = Fa[Fa[u][i-1]][i-1];
for(int e = head[u]; e; e = nxt[e])
Fa[to[e]][0] = u, build(to[e]);
return ;
} int color[maxn<<1], totc[maxn<<1], wei[maxn<<1];
int jump(int u, int W) {
for(int i = maxlog - 1; i >= 0; i--) if(Fa[u][i] && wei[Fa[u][i]] <= W) u = Fa[u][i];
return u;
} int main() {
int n = read(), m = read(), online = read();
for(int i = 1; i <= n; i++) color[i] = read();
for(int i = 1; i <= m; i++) {
int a = read(), b = read(), c = read();
es[i] = Edge(a, b, c);
} sort(es + 1, es + m + 1);
for(int i = 1; i < (n << 1); i++) {
pa[i] = i;
if(i <= n) Add(Rt[i], color[i], 1), totc[i] = 1, wei[i] = 0;
}
for(int i = 1; i <= m; i++) {
int a = findset(es[i].a), b = findset(es[i].b), c;
if(a != b) {
wei[c = ++n] = es[i].c;
if(ns[Rt[a]].siz < ns[Rt[b]].siz) swap(a, b);
Rt[c] = Rt[a]; recycle(Rt[b]);
opt = Node(color[a], totc[a], 0);
while(cnts) Add(Rt[c], Set[cnts].col, Set[cnts].val), cnts--;
color[c] = opt.col; totc[c] = opt.val;
AddEdge(c, a); AddEdge(c, b);
pa[a] = pa[b] = c;
}
}
for(int i = n; i; i--) if(!vis[i]) build(i);
// for(int i = 1; i <= n; i++) printf("%d%c", color[i], i < n ? ' ' : '\n'); int q = read(), lst = 0;
for(int k = 1; k <= q; k++) {
int x = read() ^ lst * online, w = read() ^ lst * online;
printf("%d\n", lst = color[jump(x,w)]);
} return 0;
}

[OJ#40]后宫佳丽的更多相关文章

  1. C++之路进阶——codevs4416(FFF的后宫)

    4416 FFF 团卧底的后宫  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold       题目描述 Description 你在某日收到了 FFF 团卧底的求 ...

  2. CodeVS4416 FFF 团卧底的后宫

    题目描述 Description 你在某日收到了 FFF 团卧底的求助,在他某日旅游回来,他的后宫们出现了一些不可调和的矛盾,如果 FFF 团卧底把自己的宝贝分给 a 号妹子,那么 b 号妹子至少要在 ...

  3. NOIP模拟赛 czy的后宫4

    czy的后宫4 [问题描述] czy有很多妹子,妹子虽然数量很多,但是质量不容乐观,她们的美丽值全部为负数(喜闻乐见). czy每天都要带N个妹子到机房,她们都有一个独一无二的美丽值,美丽值为-1到- ...

  4. NOIP模拟赛 czy的后宫6

    czy的后宫6 题目描述 众所周知的是丧尸czy有很多妹子(虽然很多但是质量不容乐观QAQ),今天czy把n个妹子排成一行来检阅.但是czy的妹子的质量实在……所以czy看不下去了.检阅了第i个妹子会 ...

  5. NOIP模拟赛 czy的后宫5

    描述 czy要召集他的妹子,但是由于条件有限,可能每个妹子不能都去,但每个妹子都有一个美丽值,czy希望来的妹子们的美丽值总和最大(虽然……). czy有一个周密的电话通知网络,它其实就是一棵树,根结 ...

  6. NOIP模拟赛 czy的后宫3

    [题目描述] 上次czy在机房妥善安排了他的后宫之后,他发现可以将他的妹子分为c种,他经常会考虑这样一个问题:在[l,r]的妹子中间,能挑选出多少不同类型的妹子呢? 注意:由于czy非常丧尸,所以他要 ...

  7. NOIP模拟赛 czy的后宫

    [题目描述] czy要妥善安排他的后宫,他想在机房摆一群妹子,一共有n个位置排成一排,每个位置可以摆妹子也可以不摆妹子.有些类型妹子如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看了.假定每种 ...

  8. 差分约束 4416 FFF 团卧底的后宫

    /* 4416 FFF 团卧底的后宫  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 你在某日收到了 FFF ...

  9. 【czy系列赛】czy的后宫4 && bzoj1925 [Sdoi2010]地精部落

    [问题描述] czy有很多妹子,妹子虽然数量很多,但是质量不容乐观,她们的美丽值全部为负数(喜闻乐见). czy每天都要带N个妹子到机房,她们都有一个独一无二的美丽值,美丽值为-1到-N之间的整数.他 ...

随机推荐

  1. jmeter(四)检查点

    JMeter也有像LR中的检查点,本篇就来介绍下JMeter的检查点如何去实现. JMeter里面的检查点通过添加断言来完成. 检查点:上一章讲到,我们对用户名和密码进行了参数化,那么怎样来判断jme ...

  2. Object流

  3. Netflix正式开源其API网关Zuul 2--转

    微信公众号:聊聊架构 5 月 21 日,Netflix 在其官方博客上宣布正式开源微服务网关组件 Zuul 2.Netflix 公司是微服务界的楷模,他们有大规模生产级微服务的成功应用案例,也开源了相 ...

  4. easy ui combotree的操作

    1.获取combotree的选中值 $("#id").combotree("getValue"); 2.设置combotree的选中值 $('#id').com ...

  5. jquery基础知识点总结

    Jquery是一个优秀的js库,它简化了js的复杂操作,不需要关心浏览器的兼容问题,提供了大量实用方法. Jquery的写法 方法函数化 链式操作 取值赋值合体] $(“p”).html();   取 ...

  6. Spark学习之基于MLlib的机器学习

    Spark学习之基于MLlib的机器学习 1. 机器学习算法尝试根据训练数据(training data)使得表示算法行为的数学目标最大化,并以此来进行预测或作出决定. 2. MLlib完成文本分类任 ...

  7. Android开发使用的常见第三方框架汇总

    本文转载:http://blog.csdn.net/liuhaomatou/article/details/44857005 1.volley 项目地址 https://github.com/sman ...

  8. 转:谈谈iOS中粘性动画以及果冻效果的实现

    在最近做个一个自定义PageControl——KYAnimatedPageControl中,我实现了CALayer的形变动画以及CALayer的弹性动画,效果先过目: 先做个提纲: 第一个分享的主题是 ...

  9. Linux 的 Spinlock 在 MIPS 多核处理器中的设计与实现

    引言 随着科技的发展,尤其是在嵌入式领域,高性能.低功耗的处理器成为众多厂商追逐的目标,但是由于技术和工艺的瓶颈,试图在单核处理器上达到这样的目标变得越发困难,于是人们提出了多核处理器的概念.多核处理 ...

  10. at, batch, atq, atrm - 排队、检查或删除以后要执行的作业

    总览 at [-V] [-q 队列] [-f 文件] [-mldbv] 时间 at -c 作业 [作业...] atq [-V] [-q 队列] [-v] atrm [-V] 作业 [作业...] b ...