「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. 【BZOJ】2693: jzptab 莫比乌斯反演

    [题意]2154: Crash的数字表格 莫比乌斯反演,多组询问,T<=10000. [算法]数论(莫比乌斯反演) [题解]由上一题, $ans=\sum_{g\leq min(n,m)}g\s ...

  2. 转:国内优秀npm镜像推荐及使用

    原文:http://riny.net/2014/cnpm/ npm全称Node Package Manager,是node.js的模块依赖管理工具.由于npm的源在国外,所以国内用户使用起来各种不方便 ...

  3. maven使用过程中遇到的问题总汇

    1:web.xml is missing and <failOnMissingWebXml> is set to true 造成原因: 使用maven创建项目时有时在pom.xml的war ...

  4. 【洛谷 P4542】 [ZJOI2011]营救皮卡丘(费用流)

    题目链接 用最多经过\(k\)条经过\(0\)的路径覆盖所有点. 定义\(ds[i][j]\)表示从\(i\)到\(j\)不经过大于\(max(i,j)\)的点的最短路,显然可以用弗洛伊德求. 然后每 ...

  5. Django之原生Ajax操作

    Ajax主要就是使用 [XmlHttpRequest]对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件). 先通过代码来看看Aja ...

  6. Go语言 8 反射

    文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 8.1概念和作用 Reflection(反射)在计算 ...

  7. LCD驱动分析【转】

    转自:http://blog.csdn.net/hanmengaidudu/article/details/21559153 1.S3C2440上LCD驱动 (FrameBuffer)实例开发讲解 其 ...

  8. WebHeaderCollection类

    .net添加http报头 string[] allKeys = WebHeaderCollection.AllKeys; for (int i = 0; i < allKeys.Length; ...

  9. java之正则表达式、日期操作

    正则表达式和日期操作 正则表达式简介 正则表达式就是使用一系列预定义的特殊字符来描述一个字符串的格式规则,然后使用该格式规则匹配某个字符串是否符合格式要求. 作用:比如注册邮箱,邮箱有用户名和密码,一 ...

  10. php判断是手机还是pc访问从而走不同url

    <?php header("Content-type:text/html;charset=utf-8"); function is_mobile(){ $user_agent ...