Wannafly挑战赛16 #E 弹球弹弹弹 splay+基环树+各种思维
链接:https://ac.nowcoder.com/acm/problem/16033
来源:牛客网
有n个位置,标号为1到n的整数,m次操作,第i次操作放置一个弹球在b[i] xor c[i-1]处,并询问b[i] xor c[i-1]处弹球个数c[i]
每次操作后,在x处的弹球被弹到a[x],规定c[0]=0
把球弹来弹去的位置关系刻画出来的话是一个基环树森林的结构.
每个不在环里的点会逐渐走向环,最终循环地在环里不停的转.
然后你发现如果查询不在环上的点可以用一个 $splay$ 来维护每个联通块中每一个 $dep[u]+time[u]$ 的 $dfs$ 序.
其实就是对于每一条链都以连续区间插入,这样查询的时候是区间查询.
然后对于环上的点如何查询什么时候到就自己 $yy$ 一下吧,这个我实在是想不起来了,细节多的要命.
#include<bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define rg register
#define O2 __attribute__((optimize("-O2")))
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
const int maxn=500003;
const int inf=10000000;
void setIO(string s) {
string in=s+".in";
freopen(in.c_str(),"r",stdin);
freopen("tt.out","w",stdout);
}
struct Splay {
#define lson ch[x][0]
#define rson ch[x][1]
int cnt;
int ch[maxn][2],siz[maxn],f[maxn],mn[maxn],mx[maxn],pos[maxn];
O2 inline void init() {
cnt=0,mx[0]=-inf,mn[0]=inf;
}
O2 inline int get(int x) {
return ch[f[x]][1]==x;
}
O2 inline void pushup(int x) {
siz[x]=siz[lson]+siz[rson]+1;
mx[x]=mn[x]=pos[x];
mx[x]=max(mx[x],mx[rson]);
mn[x]=min(mn[x],mn[lson]);
}
O2 inline void rotate(int x) {
int old=f[x],fold=f[old],which=get(x);
ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
ch[x][which^1]=old,f[old]=x,f[x]=fold;
if(fold) ch[fold][ch[fold][1]==old]=x;
pushup(old), pushup(x);
}
O2 inline void splay(int x,int &tar) {
int u=f[tar],fa;
for(;(fa=f[x])^u;rotate(x))
if(f[fa]^u)
rotate(get(fa)==get(x)?fa:x);
tar=x;
}
O2 void insert(int &x,int p,int ff) {
if(!x) {
x=++cnt,f[x]=ff,pos[x]=p;
pushup(x);
return;
}
insert(ch[x][p>pos[x]],p,x), pushup(x);
}
O2 int query(int x,int l,int r) {
if(!x||mx[x]<l||mn[x]>r) return 0;
if(mn[x]>=l&&mx[x]<=r) return siz[x];
int re=0;
if(pos[x]>=l&&pos[x]<=r) ++re;
return re+query(lson,l,r)+query(rson,l,r);
}
#undef lson
#undef rson
}tr;
struct Graph {
int edges;
int hd[maxn],to[maxn],nex[maxn];
O2 inline void addedge(int u,int v) {
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
}G,V;
int oo[maxn];
vector<int>mm[maxn<<1];
vector<int>cir[maxn];
unordered_map<int, vector<int> >ins[maxn];
int n,m,id,tim;
int idx[maxn],dep[maxn],dfn[maxn],st[maxn],ed[maxn],top[maxn],dis[maxn];
unordered_map<int,int>rt[maxn];
unordered_map<int,int>bu[maxn];
namespace prepare {
int du[maxn];
queue<int>Q;
O2 void dfs(int u) {
cir[idx[u]].push_back(u);
for(rg int i=V.hd[u];i;i=V.nex[i])
{
int v=V.to[i];
if(du[v]&&!idx[v]) {
idx[v]=idx[u];
dfs(v);
break;
}
}
}
O2 inline void work() {
for(rg int i=1;i<=V.edges;++i) ++du[V.to[i]];
for(rg int i=1;i<=n;++i) if(!du[i]) Q.push(i);
while(!Q.empty()) {
int u=Q.front(); Q.pop();
for(rg int i=V.hd[u];i;i=V.nex[i]) {
int v=V.to[i];
--du[v];
if(!du[v]) Q.push(v);
}
}
for(rg int i=1;i<=n;++i) {
if(!du[i]) continue;
if(!idx[i]) idx[i]=++id, dfs(i);
}
}
};
O2 void dfs(int u,int ff) {
dep[u]=dep[ff]+1,st[u]=++tim,dfn[tim]=u;
for(rg int i=G.hd[u];i;i=G.nex[i]) {
int v=G.to[i];
if(v==ff||idx[v]) continue;
top[v]=top[u],dfs(v,u);
}
ed[u]=tim;
}
O2 int main() {
// setIO("input");
n=rd();
memset(oo, -1, sizeof(oo));
for(rg int i=1;i<=n;++i) {
int x=rd();
V.addedge(i,x); // 基环树
G.addedge(x,i); // 建树
}
prepare::work(), tr.init();
for(rg int i=1;i<=id;++i)
for(rg int j=0;j<cir[i].size();++j) {
top[cir[i][j]]=cir[i][j],dep[0]=-1,dfs(cir[i][j], 0);
dis[cir[i][j]]=j;
}
m=rd();
int lastans=0;
for(rg int i=0;i<m;++i) {
int b,cur,cur_id,cur_siz;
b=rd(), b^=lastans, lastans=0;
cur_id=idx[top[b]];
cur_siz=cir[cur_id].size();
int x1 = (dis[top[b]] - (i%cur_siz) + cur_siz) % cur_siz;
int x2 = dep[b]%cur_siz;
int tmp = (x1 - x2 + cur_siz) % cur_siz;
ins[cur_id][i+dep[b]].push_back(tmp), mm[i+dep[b]].push_back(cur_id);
for(rg int o=0;o<mm[i].size();++o) {
int uu=mm[i][o];
if(oo[uu]!=i) {
oo[uu]=i;
for(rg int j=0;j<ins[uu][i].size();++j) bu[uu][ins[uu][i][j]]+=1;
}
}
if(idx[b]) lastans+=bu[cur_id][(dis[b]-(i%cur_siz)+cur_siz)%cur_siz];
else {
cur=dep[b]+i;
tr.insert(rt[cur_id][cur], st[b], 0) , tr.splay(tr.cnt, rt[cur_id][cur]);
int a=tr.query(rt[cur_id][cur],st[b],ed[b]);
lastans+=a;
}
printf("%d\n",lastans);
}
return 0;
}
Wannafly挑战赛16 #E 弹球弹弹弹 splay+基环树+各种思维的更多相关文章
- Wannafly 挑战赛16 A 取石子
题目描述 给出四堆石子,石子数分别为a,b,c,d.规定每次只能从堆顶取走石子,问取走所有石子的方案数. 输入描述: 在一行内读入四个由空格分隔的整数a,b,c,d, 输入均为不超过500的正整数 输 ...
- Wannafly挑战赛16
E(pbds) 题意: 1<=m,n<=5e5 分析: 首先指向关系形成了一个基环外向树森林 实际上我们可以完全不用真正的去移动每个球,而只需要在计数的时候考虑考虑就行了 对于树上的情况, ...
- Wannafly挑战赛10 D 小H的询问(线段树)
题目链接 Problem D 这个题类似 SPOJ GSS3 做过那个题之后其实就可以秒掉这题了. 考虑当前线段树维护的结点 在那道题的基础上,这个题要多维护几个东西,大概就是左端点的奇偶性,右端点 ...
- Wannafly挑战赛27 C蓝魔法师
链接Wannafly挑战赛27 C蓝魔法师 给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于\(k\),\(n,k\leq 2*10^3\) 假设我们正在考虑\(i\)这个子树,那么 ...
- 简单实现弹出弹框页面背景半透明灰,弹框内容可滚动原页面内容不可滚动的效果(JQuery)
弹出弹框 效果展示 实现原理 html结构比较简单,即: <div>遮罩层 <div>弹框</div> </div> 先写覆盖显示窗口的遮罩层div.b ...
- Wannafly挑战赛26-F. msc的棋盘(模型转化+dp)及一类特殊的网络流问题
题目链接 https://www.nowcoder.com/acm/contest/212/F 题解 我们先考虑如果已知了数组 \(\{a_i\}\) 和 \(\{b_i\}\),如何判断其是否合法. ...
- Wannafly 挑战赛 19 参考题解
这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...
- Wannafly挑战赛25游记
Wannafly挑战赛25游记 A - 因子 题目大意: 令\(x=n!(n\le10^{12})\),给定一大于\(1\)的正整数\(p(p\le10000)\)求一个\(k\)使得\(p^k|x\ ...
- Wannafly挑战赛27
Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...
随机推荐
- Golang中log与fmt区别
关于使用log与使用fmt的区别 最初的就是直接打印出来,之后一点点升级,比如加上输出的时间,加上goroutine之间的并发操作(打印信息并不能一定按照你规定好的顺序输出来 每次输出的顺序可能会不同 ...
- Python_ONLINE_习题集_1 递归
1.1 使用递归实现:计算某个数的阶乘 def func(x): if x == 2: return 2 else: return x*func(x-1) a = func(4) print(a) 2 ...
- 文档压缩 | gzip、bzip2、xz
6.文档的压缩与打包 Linux下常见后缀名所对应的的压缩工具 .gz 表示由gzip压缩工具压缩的文件 .bz2 表示由bzip2压缩工具压缩的文件 .tar 表示由tar打包程序打包的文件(tar ...
- 红帽学习笔记[RHCSA] 第五课[用户、权限相关]
第五课 用户权限 查看文件的权限 [kane@localhost /]$ ll total 36 ----------. 1 root root 1751 Aug 22 20:58 ~ lrwxrwx ...
- [DS+Algo] 002 一维表结构
目录 1. 顺序表 1.1 分类 1.2 实现方式 1.3 扩容问题 1.4 操作 2. 链表 2.1 分类 2.2 链表相关操作 2.3 链表 VS 顺序表 3. 关于代码实现 1. 顺序表 1.1 ...
- PostgreSQL dblink使用过程
安装: 进入/root/postgresql-11.2/contrib/dblink make && make install 切换到postgres用户 [root@fce40690 ...
- IF条件控制
条件控制 定义 Python 条件语句是通过一条或多条语句的执行结果(True 或者 False)来决定执行的代码块. 如下图所示 IF语句 if condition_1: statement_blo ...
- CentOS7使用集群同步脚本对配置文件同步分发
1.介绍 使用集群同步脚本对配置文件同步分发 2.操作 1)在/root目录下创建bin目录,并在bin目录下创建文件xsync,文件内容如下: [root@hadoop101 ~]$ mkdir b ...
- 这款多线程中间件,吊打 Redis!
Java技术栈 www.javastack.cn 优秀的Java技术公众号 今天给大家介绍的是KeyDB,KeyDB项目是从redis fork出来的分支.众所周知redis是一个单线程的kv内存存储 ...
- java-webservice的简单实现
服务端: 1.创建正常j2ee项目,创建service接口 package service; import javax.jws.WebMethod; import javax.jws.WebServi ...