来自FallDream的博客,未经允许,请勿转载,谢谢。


cut掉部分题面。

给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex
mex就是一个集合中最小的没有出现的非负整数,注意0要算
比如说集合是1,9,2,6,0,8,1,7,则出现了0,1,2,6,7,8,9这7种不同的点权,因为没有3所以mex是3
n<=100000,总共询问的链数量<=100000 权值<=30000
考虑对树分块,预处理每个块的中心到它父亲中同样是中心的点的bitset,然后查询的时候先暴力跳到中心,再能跳到上一个中心就跳,最后再暴力跳即可。
手写bitset来查询答案。
预处理复杂度$n\sqrt{n}$,每次询问复杂度是$O(\sqrt{n}+\frac{30000}{64})$
另一道由乃打扑克也是同样的做法,最后询问的时候,16位可以一起处理,预处理0-65535里面每个数低位连续的1的数量,中间的1在不同幂次下的贡献和高位连续的1的数量。
雪辉

#include<iostream>
#include<cstdio>
#define MN 100000
#define MB 320
#define MD 17
#define ull unsigned long long
#define getchar() (*S++)
char B[1<<26],*S=B;
using namespace std;
inline int read()
{int x = 0 , f = 1; char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;
}
int n,m,flag,w[MN+5],head[MN+5],cnt=0,fa[MD+5][MN+5],mx[MN+5];
int mark[MN+5],dep[MN+5],rt[MB+5],rtnum=0,top[MN+5],Num[MN+5];
struct edge{int to,next;}e[MN*2+5];
ull MAXN=0;
struct Bitset
{ull s[470];int len;void Clear(){for(int i=0;i<470;++i) s[i]=0;len=0;}void operator |=(int x){s[x>>6]|=1LL<<(x&63);len=max(len,x>>6);}void operator |=(const Bitset&y){len=max(len,y.len);for(int i=0;i<=len;++i)s[i]|=y.s[i];}int num(){int res=0;for(int i=0;i<=len;++i)res+=Num[s[i]>>48]+Num[(s[i]>>32)&65535]+Num[(s[i]>>16)&65535]+Num[s[i]&65535];return res;}int Query(){for(int i=0;i<470;++i) if(s[i]!=MAXN)for(int j=0;j<64;++j)if(!(s[i]&((ull)1<<j)))return i*64+j;}
}b[MB+5][MB+5],ans;inline void ins(int f,int t)
{e[++cnt]=(edge){t,head[f]};head[f]=cnt;e[++cnt]=(edge){f,head[t]};head[t]=cnt;
}void init(int x)
{mx[x]=dep[x];for(int i=head[x];i;i=e[i].next)if(e[i].to!=fa[0][x]){fa[0][e[i].to]=x;dep[e[i].to]=dep[x]+1;init(e[i].to);mx[x]=max(mx[x],mx[e[i].to]);}if(mx[x]-dep[x]>=MB||x==1) mx[x]=0,rt[mark[x]=++rtnum]=x;
}inline int lca(int x,int y)
{if(dep[x]<dep[y]) swap(x,y);for(int k=dep[x]-dep[y],j=0;k;k>>=1,++j)if(k&1) x=fa[j][x];if(x==y) return x;for(int i=MD;~i;--i)if(fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y];return fa[0][x];
}
int last=0;
int main()
{fread(B,1,1<<26,stdin);n=read();m=read();flag=read();for(int i=0;i<64;++i) MAXN|=(ull)1<<i;for(int i=0;i<=65536;++i)for(int j=i;j;j>>=1)Num[i]+=(j&1);for(int i=1;i<=n;++i) w[i]=read();for(int i=1;i<n;++i) ins(read(),read());dep[1]=1;init(1);for(int i=1;i<=MD;++i)for(int j=1;j<=n;++j)fa[i][j]=fa[i-1][fa[i-1][j]];for(int i=1;i<=rtnum;++i){Bitset now;now.Clear();now|=w[rt[i]];b[i][i]=now;for(int k=fa[0][rt[i]];k;k=fa[0][k]){now|=w[k];if(mark[k]){b[i][mark[k]]=now;if(!top[rt[i]]) top[rt[i]]=k;}}}for(int i=1;i<=m;++i){ans.Clear();int nn=read();for(int j=1;j<=nn;++j){int x=read(),y=read(),xx,yy;if(flag) x^=last,y^=last;int z=lca(x,y);ans|=w[x];ans|=w[y];for(;!mark[x]&&dep[x]>dep[z];)x=fa[0][x],ans|=w[x];for(;!mark[y]&&dep[y]>dep[z];)y=fa[0][y],ans|=w[y];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(;xx!=yy;){if(dep[xx]<dep[yy]) swap(xx,yy);xx=fa[0][xx];ans|=w[xx];}}int x=ans.num(),y=ans.Query();last=x+y;printf("%d %d\n",x,y);}return 0;
}

View Code

由乃打扑克

#include<iostream>
#include<cstdio>
#define MN 100000
#define MB 350
#define MD 17
#define int unsigned int
#define uint  int
#define ull unsigned long long
#define getchar() (*S++)
char B[1<<26],*S=B;
using namespace std;
inline long long read()
{long long x = 0 , f = 1; char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;
}
int n,m,w[MN+5],head[MN+5],cnt=0,fa[MD+5][MN+5],mx[MN+5];
int mark[MN+5],dep[MN+5],rt[MB+5],rtnum=0,top[MN+5],front[MN+5],back[MN+5];
uint pw[30005][32],Num[65536][32],K,last=0;
struct edge{int to,next;}e[MN*2+5];void Combine(uint&ans,uint&len,int x)
{if(x==65535) {len+=16;return;}len+=front[x];ans+=pw[len][K];ans+=Num[x][K];len=back[x];
}
struct Bitset
{ull s[470];int len;void Clear(){for(int i=0;i<470;++i) s[i]=0;len=0;}void operator |=(int x){s[x>>6]|=1LL<<(x&63);len=max(len,x>>6);}void operator |=(const Bitset&y){len=max(len,y.len);for(int i=0;i<=len;++i)s[i]|=y.s[i];}uint Query(int k){uint ans=0,L=0;for(int i=0;i<=len;++i)Combine(ans,L,s[i]&65535),Combine(ans,L,(s[i]>>16)&65535),Combine(ans,L,(s[i]>>32)&65535),Combine(ans,L,(s[i]>>48)&65535);return (ans+=pw[L][k]);}
}b[MB+5][MB+5],ans;inline void ins(int f,int t)
{e[++cnt]=(edge){t,head[f]};head[f]=cnt;e[++cnt]=(edge){f,head[t]};head[t]=cnt;
}void init(int x)
{mx[x]=dep[x];for(int i=head[x];i;i=e[i].next)if(e[i].to!=fa[0][x]){fa[0][e[i].to]=x;dep[e[i].to]=dep[x]+1;init(e[i].to);mx[x]=max(mx[x],mx[e[i].to]);}if(mx[x]-dep[x]>=MB||x==1) mx[x]=0,rt[mark[x]=++rtnum]=x;
}inline int lca(int x,int y)
{if(dep[x]<dep[y]) swap(x,y);for(int k=dep[x]-dep[y],j=0;k;k>>=1,++j)if(k&1) x=fa[j][x];if(x==y) return x;for(int i=MD;~i;--i)if(fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y];return fa[0][x];
}main()
{fread(B,1,1<<26,stdin);n=read();m=read();for(int i=1;i<=30000;++i){int k=1;pw[i][0]=1;for(int j=1;j<=30;++j)pw[i][j]=(k*=i);}for(int i=0;i<=65534;++i){int j=0,flag=0;for(int k=i,kk=1;kk<=16;++kk,k>>=1)if(k&1) ++j;else{if(!flag) flag=1,front[i]=j;else for(int kkk=0;kkk<=30;++kkk)Num[i][kkk]+=pw[j][kkk];j=0;}back[i]=j;}for(int i=1;i<=n;++i) w[i]=read();for(int i=1;i<n;++i) ins(read(),read());dep[1]=1;init(1);for(int i=1;i<=MD;++i)for(int j=1;j<=n;++j)fa[i][j]=fa[i-1][fa[i-1][j]];for(int i=1;i<=rtnum;++i){Bitset now;now.Clear();now|=w[rt[i]];b[i][i]=now;for(int k=fa[0][rt[i]];k;k=fa[0][k]){now|=w[k];if(mark[k]){b[i][mark[k]]=now;if(!top[rt[i]]) top[rt[i]]=k;}}}for(int i=1;i<=m;++i){ans.Clear();int nn=read();for(int j=1;j<=nn;++j){uint x=(read()^last),y=(read()^last),xx,yy;uint z=lca(x,y);ans|=w[x];ans|=w[y];if(x<1||x>n||y<1||y>n) return 0;for(;!mark[x]&&dep[x]>dep[z];)x=fa[0][x],ans|=w[x];for(;!mark[y]&&dep[y]>dep[z];)y=fa[0][y],ans|=w[y];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(;xx!=yy;){if(dep[xx]<dep[yy]) swap(xx,yy);xx=fa[0][xx];ans|=w[xx];}}printf("%u\n",last=ans.Query(K=read()));}return 0;
}

View Code

转载于:https://www.cnblogs.com/FallDream/p/bzoj4763.html

[bzoj4763]雪辉[bzoj4812][Ynoi2017]由乃打扑克相关推荐

  1. [洛谷]CON1466 洛谷2017春节联欢赛 Hello Dingyou题解 Bzoj4763雪辉

    题目来源:https://www.luogu.org/contest/show?tid=1466 创建时间:2017/3/13 18:33 镇楼图:       猜猜她是谁~ 解题思路: 春节居然也有 ...

  2. Bzoj4763 雪辉

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

  3. 「BZOJ4763」雪辉

    「BZOJ4763」天野雪辉 题目大意:有一棵 \(n\) 个点的树,树上每一个点有权值 \(a_i \leq 30000\) ,每次询问给出若干路径,求出这些路径的并上面的不同颜色数与 \(mex\ ...

  4. [BZOJ 4763]雪辉

    [BZOJ 4763] 雪辉 题意 给定一棵 \(n\) 个点的无根树, 点带权. \(q\) 次询问, 每次给定树上的若干路径, 求这些路径上的点共有多少种不同权值以及这些点的权值组成的集合的 \( ...

  5. 4763: 雪辉[点分治+可持久化分块]

    4763: 雪辉 Time Limit: 39 Sec  Memory Limit: 666 MB Submit: 85  Solved: 51 [Submit][Status][Discuss] D ...

  6. [BZOJ4763][P3603]雪辉[手写bitset+静态分块]

    题意:给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有出现的非负整数,注意0要算 rand出 \(\sqrt n\)个点,把每 ...

  7. [题解] 洛谷 P3603 雪辉

    模拟赛中遇到了这个题,当时我这个沙雕因为把一个\(y\)打成了\(x\)而爆零.回来重新写这道题,莫名其妙的拿了rank1... 我的解法与其他几位的题解有些不同我太蒻了.并没有选取所谓的关键点,而是 ...

  8. bzoj 4763: 雪辉

    Description 给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有出现的非负整数,注意0要算 比如说集合是1,9,2,6 ...

  9. bzoj 乱刷计划 50/50

    前言 话说第一个板刷计划由于种种原因而告一段落了..其实那一版还有很多题想做,那就只能放一放了 附上效果图一张(几乎每一题都在我博客有题解): 打算 可以复习,重做自己做过的题,不局限于没做过的 乱刷 ...

最新文章

  1. 【OpenGL】十五、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_FAN 三角形扇 )
  2. flutter dart Md5加密
  3. PHP web应用的调试
  4. ajax大数据导入的一系列问题处理
  5. 字符串拼接与打印相关2
  6. 多态应用-打印商品价格案例
  7. androidQ(10.0) 预装集成apk到data分区
  8. Matlab使用sort进行排序---2022/04/07
  9. 欧拉公式求四面体体积
  10. 计算机水平cet2是什么等级,英语cet2等级考试试题
  11. Scratch编程(十)扩展模块:视频侦测模块
  12. 实现编辑网页document.body.contentEditable
  13. 微信小程序自定义组件制作图表动画
  14. cesium 添加广告牌
  15. CSS3中steps()动画的详解
  16. 如何使用串口调试工具测试HX530串口RFID读卡器读取IC卡卡号
  17. Jzoj1967 聪聪可可
  18. 计算机在英语写作中应用,多媒体计算机技术在初中英语写作中应用.doc
  19. 当经历所有大厂的实习面试过后
  20. 小米日历和WIN10自带日历的日程同步

热门文章

  1. java static 变量存在哪_Java中的静态方法和静态变量存储在哪里?
  2. anaconda 更改路径_一文教你如何运用Anaconda帮助Python编程
  3. Linux c++ udp按包发送接收文件
  4. 数据库期末总结笔记( 零基础 )
  5. 牛客网暑期ACM多校训练营(第十场): H. Rikka with Ants(类欧几里得)
  6. bzoj 3036: 绿豆蛙的归宿(Dp)
  7. bzoj 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐(DP)
  8. SPFA差分约束(bzoj 2330: [SCOI2011]糖果)
  9. [Python] 函数来判断一个对象是否是一个已知的类型:isinstance(object, classinfo)
  10. Python: SystemError: Unknown opcode