Bzoj4763 雪辉
Time Limit: 39 Sec Memory Limit: 666 MB
Submit: 151 Solved: 80
Description
Input
Output
Sample Input
0 0 1 0 0 2 2 0 0 0
2 3
1 2
4 5
3 4
7 8
6 7
5 6
9 10
8 9
4
1 7
3 3
1 1
9 3
Sample Output
HINT
Source
树 树分块 bitset
询问区间mex,理论上桶是必须要开的。这题强制在线不能树上莫队,那就只能用bitset即时维护了。
直接爬树链显然不可取,我们可以考虑树分块。
统计一条链(x,y)的答案时,拆成(x,LCA)和(y,LCA)分别处理,先向上跳到当前点所在块的中心,然后整块往上跳,再跳完零碎的部分。
因为我们要查询的是链的信息,和区域无关,所以分块应该按照深度分而不是子树大小。
stl的bitset不支持询问mex,所以要手写bitset
博主码代码的时候出现了很多细节上的问题,导致复杂度不稳定,无情被卡。
这是一个悲伤的故事,这个故事告诉我们永远不要迷之自信地认为自己的诡异写法能艹过正解。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define UL long long
using namespace std;
const int mxn=;
const UL ful=0xFFFFFFFFFFFFFFFF;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*-''+ch;ch=getchar();}
return x*f;
}
void write(int x){
if(x>)write(x/);
putchar(''+x%);
return;
}
struct edge{
int v,nxt;
}e[mxn<<];
int hd[mxn],mct=;
void add_edge(int u,int v){
e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
}
//
int num[];
struct BIT{
UL x[];
inline void clear(){memset(x,,sizeof x);return;}
void insert(int a){
int pos=a/+;
x[pos]|=1LL<<(a%);
return;
}
void operator |= (const BIT &b){
for(register int i=;i<;i++)x[i]|=b.x[i];
return;
}
int mex(){
for(int i=;i<;i++){
if(x[i]!=ful){
int res=;
UL tmp=x[i];
while(tmp&){
res++;
tmp>>=;
}
return res+(i-)*;
}
}
return *-;
}
int calc(){
int cnt=;
for(int i=;i<;i++){
if(!x[i])continue;
if(x[i]==ful)cnt+=;
else{
UL tmp=x[i];
cnt+=num[(tmp&)]+num[(tmp>>)&];
tmp>>=;
cnt+=num[(tmp&)]+num[(tmp>>)&];
}
}
return cnt;
}
}bt[][],res;
int block=;
int dep[mxn],mx[mxn],bct=;
int Cid[mxn],C[mxn],Cfa[mxn];
int fa[mxn][];
void DFS(int u,int ff){
mx[u]=;dep[u]=dep[ff]+;
for(int i=;i<=;i++)fa[u][i]=fa[fa[u][i-]][i-];
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;if(v==ff)continue;
fa[v][]=u;
DFS(v,u);
mx[u]=max(mx[u],mx[v]+);
}
if(mx[u]>=block || u==){
mx[u]=;
bct++; Cid[u]=bct; C[bct]=u; Cfa[bct]=;
}
return;
}
int LCA(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=;i>=;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][];
}
int n,Q,F;
int lastans=;
int w[mxn];
void Build(){
block=sqrt(n+0.5);
DFS(,);
for(int i=;i<=bct;i++){
int u=C[i];
res.clear();
res.insert(w[u]);u=fa[u][];
while(u){
res.insert(w[u]);
//
if(Cid[u]){
bt[i][Cid[u]]=res;
if(!Cfa[i])Cfa[i]=u;
}
//
u=fa[u][];
}
}
return;
}
void query(int x,int y){
if(dep[x]<dep[y])swap(x,y);
if(dep[x]-dep[y]<=block){
while(dep[x]>=dep[y]){
res.insert(w[x]);
x=fa[x][];
}
return;
}
while(dep[x]>=dep[y] && !Cid[x]){
res.insert(w[x]);
x=fa[x][];
}
int tmp=x;
while(dep[Cfa[Cid[tmp]]]>=dep[y]){
tmp=Cfa[Cid[tmp]];
}
if(tmp^x)res|=bt[Cid[x]][Cid[tmp]];
x=tmp;
while(dep[x]>=dep[y]){
res.insert(w[x]);
x=fa[x][];
}
return;
}
void solve(){
int a=read(),x,y;
res.clear();
while(a--){
x=read();y=read();
if(F){x^=lastans;y^=lastans;}
//
int tmp=LCA(x,y);
query(x,tmp);query(y,tmp);
//
}
int ans1=res.mex();
int ans2=res.calc();
// printf("%d %d\n",ans2,ans1);
write(ans2);putchar(' ');write(ans1);puts("");
lastans=ans1+ans2;//
return;
}
int main(){
// freopen("in.txt","r",stdin);
// freopen("out2.txt","w",stdout);
int i,j,u,v;
n=read();Q=read();F=read();
for(i=;i<=n;i++)w[i]=read();
for(i=;i<n;i++){
u=read();v=read();
add_edge(u,v);
add_edge(v,u);
}
for(i=;i<=;i++){
int tmp=i;
while(tmp){
num[i]++;
tmp-=tmp&-tmp;
}
}
Build();
while(Q--)solve();
return ;
}
Bzoj4763 雪辉的更多相关文章
- [bzoj4763]雪辉&[bzoj4812][Ynoi2017]由乃打扑克
来自FallDream的博客,未经允许,请勿转载,谢谢. cut掉部分题面. 给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有 ...
- 「BZOJ4763」雪辉
「BZOJ4763」天野雪辉 题目大意:有一棵 \(n\) 个点的树,树上每一个点有权值 \(a_i \leq 30000\) ,每次询问给出若干路径,求出这些路径的并上面的不同颜色数与 \(mex\ ...
- [BZOJ 4763]雪辉
[BZOJ 4763] 雪辉 题意 给定一棵 \(n\) 个点的无根树, 点带权. \(q\) 次询问, 每次给定树上的若干路径, 求这些路径上的点共有多少种不同权值以及这些点的权值组成的集合的 \( ...
- [题解] 洛谷 P3603 雪辉
模拟赛中遇到了这个题,当时我这个沙雕因为把一个\(y\)打成了\(x\)而爆零.回来重新写这道题,莫名其妙的拿了rank1... 我的解法与其他几位的题解有些不同我太蒻了.并没有选取所谓的关键点,而是 ...
- 洛谷P3603 || bzoj 4763 雪辉 && bzoj4812: [Ynoi2017]由乃打扑克
https://www.luogu.org/problemnew/show/P3603 https://www.lydsy.com/JudgeOnline/problem.php?id=4763 就是 ...
- MVC |分部视图 PartialView()
介绍如何定义 其实它和普通视图没有多大区别,只是创建分部视图的时候视图里没有任何内容,你需要什么标签你自己加.第二就是分部视图不会执行_ViewStart.cshtml中的内容) 控制器 Partia ...
- 【刷题】洛谷 P3613 睡觉困难综合征
题目背景 刚立完Flag我就挂了WC和THUWC... 时间限制0.5s,空间限制128MB 因为Claris大佬帮助一周目由乃通过了Deus的题,所以一周目的由乃前往二周目世界找雪辉去了 由于二周目 ...
- [Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)
4722: 由乃 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 360 Solved: 131[Submit][Status][Discuss] D ...
- 通过getElementById来取得Form里的表单元素
<1> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>湖南易通 ...
随机推荐
- ORACLE LOG的管理
CREATE OR REPLACE PACKAGE PLOG IS /** * package name : PLOG *<br/> *<br/> *See : <a h ...
- THREE.JS(如何想场景中添加物体对象)
这篇主要实现向模型对象中添加头像,并组成一个矩形 一.three.js是什么? 上篇说了点TWEEN这篇又来一根THREE是不是两兄弟啊?还真有点像,当想要做3D动画的时候,可能会考虑用TWEEN的动 ...
- call()方法和apply()方法
最近又遇到了JacvaScript中的call()方法和apply()方法,而在某些时候这两个方法还确实是十分重要的,那么就让我总结这两个方法的使用和区别吧. 1. 每个函数都包含两个非继承而来的方法 ...
- 给表格控件DBGrid加上记录序号的列
DBGrid使用起来还是很方便的,但就是没有显示记录序号的功能,必须自己加,参照老外给的解决方案如下: 方案1: 1- 在DBGrid建一个第一列 (列的名字起“NO”) 2- 在DBGrid事件 D ...
- CentOS6.7的安装
VMware9的安装请阅读: http://www.cnblogs.com/duanji/p/yueding.html CentOS6.7在VMware9中安装 1.启动VMware的画面 2.点击 ...
- 013 BIO、NIO、AIO的区别
作者:nnngu GitHub:https://github.com/nnngu 博客园:http://www.cnblogs.com/nnngu 简书:https://www.jianshu.com ...
- 洛谷 P2751 [USACO4.2]工序安排Job Processing 解题报告
P2751 [USACO4.2]工序安排Job Processing 题目描述 一家工厂的流水线正在生产一种产品,这需要两种操作:操作A和操作B.每个操作只有一些机器能够完成. 上图显示了按照下述方式 ...
- bzoj 3779: 重组病毒
一道好题~~ 一个点到根传染需要的时间是这段路径上不同颜色的数目,一个点子树到根平均传染时间就是加权平均数了(好像是废话). 所以只要用线段树维护dfs序就这个可以了,换根的话一个点的子树要么在dfs ...
- 卡特兰数Catalan——定义、公式、模型总结
推荐:卡特兰数总结 定义: f(i)表示,从(0,0)出发,到(i,i),每次只能向上或者向右走,并且不越过红线的方案数. 这个图片的点上的数字,其实告诉我们f[i],就可以根据这个n方dp得到. 其 ...
- nodejs调用脚本(python/shell)和系统命令
每种语言都有自己的优势,互相结合起来各取所长程序执行起来效率更高或者说哪种实现方式较简单就用哪个,nodejs是利用子进程来调用系统命令或者文件,文档见http://nodejs.org/api/ch ...