bzoj4763
$分块$
$一个很有趣的技巧$
$在树上选sqrt(n)个关键点,每两个关键点之间的距离<=sqrt(n),每个关键点属于一条链$
$预处理出每两个关键点的bitset$
$每次询问就暴力向上爬,合并bitset$
$由于要查询,所以要手写bitset$
- #include<bits/stdc++.h>
- using namespace std;
- typedef unsigned long long ull;
- const int bl = , N = 1e5 + ;
- ull Num[];
- vector<int> G[N];
- int n, m, f, bbl, last;
- ull Max;
- int fa[N][], dep[N], mx[N], w[N], mark[N], top[N], mir[N];
- int read() {
- int x = , f = ;
- char c = getchar();
- while(!isdigit(c)) {
- if(c == '-') {
- f = -;
- }
- c = getchar();
- }
- while(isdigit(c)) {
- x = x * + c - '';
- c = getchar();
- }
- return x * f;
- }
- struct Bitset {
- int len;
- ull s[bl];
- void clear() {
- for(int i = ; i <= len; ++i) {
- s[i] = ;
- }
- len = ;
- }
- void operator |= (const Bitset &a) {
- len = max(len, a.len);
- for(int i = ; i <= len; ++i) {
- s[i] |= a.s[i];
- }
- }
- void operator |= (int b) {
- len = max(len, b >> );
- s[b >> ] |= 1LL << (b & );
- }
- int num() {
- int ret = ;
- for(int i = ; i <= len; ++i) {
- ret += Num[s[i] >> ] + Num[(s[i] >> ) & ] + Num[(s[i] >> ) & ] + Num[s[i] & ];
- }
- return ret;
- }
- int mex() {
- for(int i = ; i <= len; ++i) {
- if(s[i] != Max) {
- for(int j = ; j < ; ++j) {
- if(!(s[i] & (1LL << j))) {
- return i * + j;
- }
- }
- }
- }
- }
- } b[][], ans;
- void dfs(int u) {
- mx[u] = dep[u];
- for(int i = ; i < G[u].size(); ++i) {
- int v = G[u][i];
- if(v == fa[u][]) {
- continue;
- }
- fa[v][] = u;
- dep[v] = dep[u] + ;
- dfs(v);
- mx[u] = max(mx[u], mx[v]);
- }
- if(mx[u] - dep[u] >= bbl || u == ) {
- mark[u] = ++mark[];
- mir[mark[u]] = u;
- mx[u] = ;
- }
- }
- int lca(int u, int v) {
- if(dep[u] < dep[v]) {
- swap(u, v);
- }
- int d = dep[u] - dep[v];
- for(int i = ; i < ; ++i) {
- if(d & ( << i)) {
- u = fa[u][i];
- }
- }
- if(u == v) {
- return u;
- }
- for(int i = ; i >= ; --i) {
- if(fa[u][i] != fa[v][i]) {
- u = fa[u][i];
- v = fa[v][i];
- }
- }
- return fa[u][];
- }
- int main() {
- n = read();
- m = read();
- f = read();
- bbl = sqrt(n);
- for(int i = ; i < ; ++i) {
- Max |= 1LL << i;
- }
- for(int i = ; i < ; ++i) {
- for(int j = ; j < ; ++j) {
- if(i & ( << j)) {
- ++Num[i];
- }
- }
- }
- for(int i = ; i <= n; ++i) {
- w[i] = read();
- }
- for(int i = ; i < n; ++i) {
- int u = read(), v = read();
- G[u].push_back(v);
- G[v].push_back(u);
- }
- dep[] = ;
- dfs();
- for(int j = ; j <= ; ++j) {
- for(int i = ; i <= n; ++i) {
- fa[i][j] = fa[fa[i][j - ]][j - ];
- }
- }
- for(int i = ; i <= mark[]; ++i) {
- ans.clear();
- ans |= w[mir[i]];
- int x;
- b[i][i] |= w[mir[i]];
- for(x = fa[mir[i]][]; x; x = fa[x][]) {
- ans |= w[x];
- if(mark[x]) {
- b[i][mark[x]] = ans;
- if(!top[mir[i]]) {
- top[mir[i]] = x;
- }
- }
- }
- }
- while(m--) {
- int a = read(), x, y, z;
- ans.clear();
- while(a--) {
- x = read();
- y = read();
- if(f) {
- x = x ^ last;
- y = y ^ last;
- }
- ans |= w[x];
- ans |= w[y];
- z = lca(x, y);
- for(; x && !mark[x] && dep[x] > z; x = fa[x][]) {
- ans |= w[x];
- }
- for(; y && !mark[y] && dep[y] > z; y = fa[y][]) {
- ans |= w[y];
- }
- int xx, yy;
- for(xx = x; dep[top[xx]] >= dep[z]; xx = top[xx]);
- for(yy = y; dep[top[yy]] >= dep[z]; yy = top[yy]);
- ans |= b[mark[x]][mark[xx]];
- ans |= b[mark[y]][mark[yy]];
- for(x = xx; dep[x] >= dep[z]; x = fa[x][]) {
- ans |= w[x];
- }
- for(y = yy; dep[y] >= dep[z]; y = fa[y][]) {
- ans |= w[y];
- }
- }
- int ta = ans.num(), tb = ans.mex();
- last = ta + tb;
- printf("%d %d\n", ta, tb);
- }
- return ;
- }
bzoj4763的更多相关文章
- 「BZOJ4763」雪辉
「BZOJ4763」天野雪辉 题目大意:有一棵 \(n\) 个点的树,树上每一个点有权值 \(a_i \leq 30000\) ,每次询问给出若干路径,求出这些路径的并上面的不同颜色数与 \(mex\ ...
- [bzoj4763]雪辉&[bzoj4812][Ynoi2017]由乃打扑克
来自FallDream的博客,未经允许,请勿转载,谢谢. cut掉部分题面. 给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有 ...
- Bzoj4763 雪辉
Time Limit: 39 Sec Memory Limit: 666 MBSubmit: 151 Solved: 80 Description 上次立下的NOIP退役Flag没有成功 这次 ...
- bzoj2589: Spoj 10707 Count on a tree II
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v),你需要回答u xor lastans和v这两个节点间有多少种不同的点权.其中lastans是上一个询问的答案,初 ...
随机推荐
- 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)
[0]写在前面 0.1)本代码旨在演示 从 ring0 转移到 ring3(即,从高特权级 转移到 低特权级) 0.2)本文 只对 与 门相关的 代码进行简要注释,言简意赅: 0.3)文末的个人总结是 ...
- liunx 安装工具总结
1 下载相关文件,比如hadoop 2 解压文件 tar -zxcf xxx.tar.gz 3 mv xxx 到指定目录:通常安装到/usr/local 或者自己建个目录 /usr/develo ...
- 1194: [HNOI2006]潘多拉的盒子
1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 464 Solved: 221[Submit][Stat ...
- HTML 学习笔记 JQuery(animation)
动画效果也是JQuery库吸引人的地方,通过JQuery的动画方法,能够轻松的为网页天假非常紧菜的视觉效果. show()方法和hide()方法 show()方法和hide()方法是JQuery中最基 ...
- hdoj 1116 Play on Words 【并查集】+【欧拉路】
Play on Words Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- while 循环中的break continue pass 的用法
while break:跳出最近的循环 continue:跳到最近所在循环的开头处 pass:什么也不做,只是空占位语句,它本身与循环没什么关系,但属于简单的单个单词语句的范畴: pass 语句是无运 ...
- springmvc fastjson 反序列化时间格式化
第一种情况是从后台拿到数据,进行反序列化,反序列化格式时间:试了一下很多网上的方法,最后发现还是在实体类上面的日期字段加上如下注解,可以完成格式化操作,否则默认就都是时间戳的格式: @JSONFiel ...
- camera报错经典问题
--- 33u>: error: undefined reference to 'NSFeature::RAWSensorInfo<22133u>::impGetDefaultDat ...
- Contiki 2.7 Makefile 文件(一)
一.主控Makefile 这里以hello-world例子为主线,从其工程Makefile开始,解析整个build过程.
- Vue.js devtool插件安装后无法使用的解决办法
初次使用Vue.js devtool插件的新人在安装了Vue.js devtool插件后,都会经常有一个疑问.我在chrome浏览器里面已经成功安装好Vue.js devtool插件,怎么点击后提示v ...