「BZOJ4763」天野雪辉

题目大意:有一棵 \(n\) 个点的树,树上每一个点有权值 \(a_i \leq 30000\) ,每次询问给出若干路径,求出这些路径的并上面的不同颜色数与 \(mex\)。\(n ,m\leq 10^5\)。

解题思路:solution1:直接树分块,每个点维护其到第一个关键祖先的一个 \(\text{bitset}\) 并暴力添加两端的答案。solution2:对树的括号序列分块,把左括号看做 \(1\) ,右括号看做 \(-1\)。维护出任意两个块之间的 \(\text{bitset}\),暴力添加两端的答案。由于不能保证任意时刻每个颜色的数量非负,所以还要在对于每个块的前缀维护个桶来记录颜色当前的数量,方便两端暴力加颜色时维护答案,复杂度都是 \(O(m\sqrt{n}+\frac{30000m}{w})\)。

另外 \(\text{bitset}\) 好像不太支持找 \(mex\) 不过可以手写或者选择下划线开头的函数 \(\text{_Find_first()}\) 。

code

/*program by mangoyang*/
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define rint register int
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
namespace FastIO{
inline char read() {
static const int IN_LEN = 1000000;
static char buf[IN_LEN], *s, *t;
return (s == t ? t = (s = buf) + fread(buf, 1, IN_LEN, stdin),(s == t ? -1 : *s++) : *s++);
}
template<class T>
inline void read(T &x) {
static bool iosig;
static char c;
for(iosig = false, c = read(); !isdigit(c); c = read()) {
if (c == '-') iosig = true;
if (c == -1) return;
}
for(x = 0; isdigit(c); c=read()) x = ((x + (x << 2)) << 1) + (c ^ '0');
if(iosig) x = - x;
}
const int OUT_LEN = 10000000;
char obuf[OUT_LEN], *ooh = obuf;
inline void print(char c) {
if (ooh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), ooh = obuf;
*ooh++=c;
}
template<class T>
inline void print(T x) {
static int buf[30], cnt;
if(x == 0) print('0');
else{
if(x < 0) print('-'), x = -x;
for(cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48;
while(cnt) print((char)buf[cnt--]);
}
}
inline void flush() { fwrite(obuf, 1, ooh - obuf, stdout); }
}
using namespace FastIO;
const int N = 200005, M = 30000, SZ = 347;
#define fi first
#define se second
bitset<M+1> Ans[SZ][SZ];
int ldfn[N], rdfn[N], ql[N], qr[N], tmp[M+1], buf[SZ][M+1], a[N], n, m, op, Size, block;
namespace tree{
vector<int> g[N];
int f[N][18], dep[N], cnt;
inline void dfs(int u, int fa){
ldfn[u] = ++cnt, ql[cnt] = a[u], qr[cnt] = 1;
f[u][0] = fa, dep[u] = dep[fa] + 1;
for(int i = 1; i <= 17; i++) f[u][i] = f[f[u][i-1]][i-1];
for(int i = 0; i < g[u].size(); i++)
if(g[u][i] != fa) dfs(g[u][i], u);
rdfn[u] = ++cnt, ql[cnt] = a[u], qr[cnt] = -1;
}
inline int lca(int x, int y){
if(dep[x] < dep[y]) swap(x, y);
for(int i = 17; ~i; i--)
if(dep[f[x][i]] >= dep[y]) x = f[x][i];
if(x == y) return x;
for(int i = 17; ~i; i--)
if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
return f[x][0];
}
}
#define bel(x) ((x - 1) / Size + 1)
#define L(x) ((x - 1) * Size + 1)
#define R(x) (Min(x * Size, n))
inline bitset<M+1> query(int l, int r){
bitset<M+1> res;
if(bel(l) + 1 >= bel(r)){
for(rint i = l; i <= r; i++){
if(!tmp[ql[i]] && ~qr[i]) res[ql[i]] = 1;
else if(tmp[ql[i]] == 1 && qr[i] == -1) res[ql[i]] = 0;
tmp[ql[i]] += qr[i];
}
for(rint i = l; i <= r; i++) tmp[ql[i]] = 0;
return res;
}
int lx = bel(l) + 1, rx = bel(r) - 1; res = Ans[lx][rx];
for(rint i = l; i < L(lx); i++){
if(!(tmp[ql[i]] + buf[rx][ql[i]] - buf[lx-1][ql[i]]) && ~qr[i]) res[ql[i]] = 1;
else if((tmp[ql[i]] + buf[rx][ql[i]] - buf[lx-1][ql[i]]) == 1 && qr[i] == -1) res[ql[i]] = 0;
tmp[ql[i]] += qr[i];
}
for(rint i = R(rx) + 1; i <= r; i++){
if(!(tmp[ql[i]] + buf[rx][ql[i]] - buf[lx-1][ql[i]]) && ~qr[i]) res[ql[i]] = 1;
else if((tmp[ql[i]] + buf[rx][ql[i]] - buf[lx-1][ql[i]]) == 1 && qr[i] == -1) res[ql[i]] = 0;
tmp[ql[i]] += qr[i];
}
for(rint i = l; i < L(lx); i++) tmp[ql[i]] = 0;
for(rint i = R(rx) + 1; i <= r; i++) tmp[ql[i]] = 0;
return res;
}
signed main(){
read(n), read(m), read(op);
for(int i = 1; i <= n; i++) read(a[i]);
for(int i = 1, x, y; i < n; i++){
read(x), read(y);
tree::g[x].push_back(y), tree::g[y].push_back(x);
}
tree::dfs(1, 0), n <<= 1;
Size = 580, block = n / Size + ((n % Size) ? 1 : 0);
for(int i = 1; i <= n; i++) buf[bel(i)][ql[i]] += qr[i];
for(int i = 2; i <= block; i++)
for(int j = 0; j <= M; j++) buf[i][j] += buf[i-1][j];
for(int i = 1; i <= block; i++){
bitset<M+1> now;
for(int j = L(i); j <= n; j++){
if(bel(j) != bel(j-1) && bel(j) > i) Ans[i][bel(j)-1] = now;
int x = ql[j], y = qr[j];
if(tmp[x] <= 0 && tmp[x] + y > 0) now[x] = 1;
if(tmp[x] > 0 && tmp[x] + y <= 0) now[x] = 0;
tmp[x] += y;
}
Ans[i][Size] = now, memset(tmp, 0, sizeof(tmp));
}
int lastans = 0;
for(rint i = 1, x, y, num; i <= m; i++){
read(num); bitset<M+1> res;
for(rint j = 1; j <= num; j++){
read(x), x ^= (lastans * op), read(y), y ^= (lastans * op);
int lca = tree::lca(x, y);
res |= query(ldfn[lca], ldfn[x]) | query(ldfn[lca], ldfn[y]);
}
int ans1 = res.count(), ans2 = (ans1 == M + 1 ? M + 1 : 0);
if(!ans2) res.flip(), ans2 = res._Find_first();
lastans = ans1 + ans2;
print(ans1), print(' '), print(ans2), print('\n');
}
flush();
return 0;
}

「BZOJ4763」雪辉的更多相关文章

  1. [bzoj4763]雪辉&[bzoj4812][Ynoi2017]由乃打扑克

    来自FallDream的博客,未经允许,请勿转载,谢谢. cut掉部分题面. 给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有 ...

  2. Bzoj4763 雪辉

    Time Limit: 39 Sec  Memory Limit: 666 MBSubmit: 151  Solved: 80 Description 上次立下的NOIP退役Flag没有成功   这次 ...

  3. 一个「学渣」从零开始的Web前端自学之路

    从 13 年专科毕业开始,一路跌跌撞撞走了很多弯路,做过餐厅服务员,进过工厂干过流水线,做过客服,干过电话销售可以说经历相当的“丰富”. 最后的机缘巧合下,走上了前端开发之路,作为一个非计算机专业且低 ...

  4. 一本通1648【例 1】「NOIP2011」计算系数

    1648: [例 1]「NOIP2011」计算系数 时间限制: 1000 ms         内存限制: 524288 KB [题目描述] 给定一个多项式 (ax+by)k ,请求出多项式展开后 x ...

  5. 「JSOI2015」子集选取

    「JSOI2015」子集选取 传送门 看到这个数据范围,就知道肯定是要找规律. 如果把集合看成一个长度为 \(n\) 的 \(01\) 串, \(0\) 表示没有这个元素, \(1\) 表示有这个元素 ...

  6. 「CometOJ」Contest #11

    Link Aeon 显然字典序最大就是把最小的字母放在最后 Business [动态规划] 简单dp dp[i][j]dp[i][j]dp[i][j]表示到第iii天,当前有jjj块钱,最后返还的钱最 ...

  7. 「MoreThanJava」Day 4:面向对象基础

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  8. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  9. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

随机推荐

  1. LintCode题解之子树

    思路: 最简单的方法,依次遍历比较就可以了. AC代码: /** * Definition of TreeNode: * public class TreeNode { * public int va ...

  2. Unity 添加鼠标右键事件

    把此类放到 Editor下使用就OK using UnityEngine; using System.Collections; using System.Collections.Generic; us ...

  3. uboot之---make smdk2410_config命令详细解析

    先进入顶层Makefile.有很多相对不同板子的配置,如: gec2440_config:unconfig @$(MKCONFIG) $(@:_config=) arm arm920t gec2440 ...

  4. UVA 1103 How Many O's?

    题目链接:UVA-11038 题意为给定n和m,求n和m之间(包含)的所有数包含的0的个数. 思路是,用cal(x)表示小于等于x的数包含的0的个数.则答案为cal(n)-cal(m-1). 再把求c ...

  5. 「pycaffe指南」使用caffe的NetSpec.py中的Python接口自动生成×.prototxt文件

    https://www.jianshu.com/p/1a420445deea 作者:MapReducer 链接:https://www.jianshu.com/p/1a420445deea 來源:简书 ...

  6. spring data jpa条件分组查询及分页

    原book对象 package com.shaying.domain; import javax.persistence.Column; import javax.persistence.Entity ...

  7. Ubuntu 各版本的几个国内更新源

    Ubuntu 国内更新源(各版本通用) 前言:为了下载更方便,速度更快,我们在使用Linux系列系统时修改 apt源 为国内的源 1.复制源文件备份,以防万一 修改文件sources.list,在目录 ...

  8. Django 中form的用法

    form的主要作用:1.在html中生成表单框架,2.验证数据(实话实说,很简洁,但不实用,灵活性差) from django.db import models # Create your model ...

  9. 洛谷P1615 西游记公司 题解

    题目传送门 这道题题面写得非常好. 但好像并没有什么ruan用. 这道题貌似就是把时间差求出来,乘上猪八戒能偷的电脑数就好了.(注意long long) #include<bits/stdc++ ...

  10. MVC – 4.mvc初体验(2)

    5.显示学员列表 效果 数据表 5.1 首先,在文件夹Models新建一个新建项(W),选择ADO.NET 实体数据模型 (SingleTest.edmx) 5.2 建一个控制器,StudentsCo ...