链接: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+基环树+各种思维的更多相关文章

  1. Wannafly 挑战赛16 A 取石子

    题目描述 给出四堆石子,石子数分别为a,b,c,d.规定每次只能从堆顶取走石子,问取走所有石子的方案数. 输入描述: 在一行内读入四个由空格分隔的整数a,b,c,d, 输入均为不超过500的正整数 输 ...

  2. Wannafly挑战赛16

    E(pbds) 题意: 1<=m,n<=5e5 分析: 首先指向关系形成了一个基环外向树森林 实际上我们可以完全不用真正的去移动每个球,而只需要在计数的时候考虑考虑就行了 对于树上的情况, ...

  3. Wannafly挑战赛10 D 小H的询问(线段树)

    题目链接  Problem D 这个题类似 SPOJ GSS3 做过那个题之后其实就可以秒掉这题了. 考虑当前线段树维护的结点 在那道题的基础上,这个题要多维护几个东西,大概就是左端点的奇偶性,右端点 ...

  4. Wannafly挑战赛27 C蓝魔法师

    链接Wannafly挑战赛27 C蓝魔法师 给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于\(k\),\(n,k\leq 2*10^3\) 假设我们正在考虑\(i\)这个子树,那么 ...

  5. 简单实现弹出弹框页面背景半透明灰,弹框内容可滚动原页面内容不可滚动的效果(JQuery)

    弹出弹框 效果展示 实现原理 html结构比较简单,即: <div>遮罩层 <div>弹框</div> </div> 先写覆盖显示窗口的遮罩层div.b ...

  6. Wannafly挑战赛26-F. msc的棋盘(模型转化+dp)及一类特殊的网络流问题

    题目链接 https://www.nowcoder.com/acm/contest/212/F 题解 我们先考虑如果已知了数组 \(\{a_i\}\) 和 \(\{b_i\}\),如何判断其是否合法. ...

  7. Wannafly 挑战赛 19 参考题解

    这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...

  8. Wannafly挑战赛25游记

    Wannafly挑战赛25游记 A - 因子 题目大意: 令\(x=n!(n\le10^{12})\),给定一大于\(1\)的正整数\(p(p\le10000)\)求一个\(k\)使得\(p^k|x\ ...

  9. Wannafly挑战赛27

    Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...

随机推荐

  1. Golang中log与fmt区别

    关于使用log与使用fmt的区别 最初的就是直接打印出来,之后一点点升级,比如加上输出的时间,加上goroutine之间的并发操作(打印信息并不能一定按照你规定好的顺序输出来 每次输出的顺序可能会不同 ...

  2. 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 ...

  3. 文档压缩 | gzip、bzip2、xz

    6.文档的压缩与打包 Linux下常见后缀名所对应的的压缩工具 .gz 表示由gzip压缩工具压缩的文件 .bz2 表示由bzip2压缩工具压缩的文件 .tar 表示由tar打包程序打包的文件(tar ...

  4. 红帽学习笔记[RHCSA] 第五课[用户、权限相关]

    第五课 用户权限 查看文件的权限 [kane@localhost /]$ ll total 36 ----------. 1 root root 1751 Aug 22 20:58 ~ lrwxrwx ...

  5. [DS+Algo] 002 一维表结构

    目录 1. 顺序表 1.1 分类 1.2 实现方式 1.3 扩容问题 1.4 操作 2. 链表 2.1 分类 2.2 链表相关操作 2.3 链表 VS 顺序表 3. 关于代码实现 1. 顺序表 1.1 ...

  6. PostgreSQL dblink使用过程

    安装: 进入/root/postgresql-11.2/contrib/dblink make && make install 切换到postgres用户 [root@fce40690 ...

  7. IF条件控制

    条件控制 定义 Python 条件语句是通过一条或多条语句的执行结果(True 或者 False)来决定执行的代码块. 如下图所示 IF语句 if condition_1: statement_blo ...

  8. CentOS7使用集群同步脚本对配置文件同步分发

    1.介绍 使用集群同步脚本对配置文件同步分发 2.操作 1)在/root目录下创建bin目录,并在bin目录下创建文件xsync,文件内容如下: [root@hadoop101 ~]$ mkdir b ...

  9. 这款多线程中间件,吊打 Redis!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 今天给大家介绍的是KeyDB,KeyDB项目是从redis fork出来的分支.众所周知redis是一个单线程的kv内存存储 ...

  10. java-webservice的简单实现

    服务端: 1.创建正常j2ee项目,创建service接口 package service; import javax.jws.WebMethod; import javax.jws.WebServi ...