链接: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. gts测试流程

    测试目的: 用于检测你做的Android gms包是否满足兼容性要求,通俗点说,gms包,就是Google自己的apk,提供基础服务,例如YouTube.playstore等. 测试前提: 1.发货u ...

  2. Tensorflow模型保存与载入

    import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #载入数据集 mnist = in ...

  3. 20191118 Spring Boot官方文档学习(4.9)

    4.9.安全 如果Spring Security在类路径上,则默认情况下Web应用程序是采用的.Spring Boot依靠Spring Security的内容协商策略来确定使用httpBasic还是f ...

  4. UrlConnection发送http请求 中文乱码解决

    中文乱码 DataOutputStream dos = new DataOutputStream(httpConn.getOutputStream()); //dos.writeBytes(jsonD ...

  5. MySql-Mysql技术内幕~SQL编程学习笔记(N)

    1._rowid 类似Oracle的rowid mysql> ; +-------+----+----------------+-------------+---------------+--- ...

  6. 太原fpxt招标

    5.31号13点多赶到太原,到yy公司,准备参加6.1号的jzfpxt投标,一起到yy山西分公司的还有北京yy总公司D工,Y工,W工等, D工负责标书及系统演示,我主要是根据D工的演示思路调整系统,演 ...

  7. Dubbo 序列化协议 5 连问,你接得住不?

    1)dubbo 支持哪些通信协议? 2)支持哪些序列化协议? 3)说一下 Hessian 的数据结构? 4)PB 知道吗? 5)为什么 PB 的效率是最高的? 面试官心理分析 上一个问题,说说 dub ...

  8. 《剑指offer》面试题23 从上往下打印二叉树 Java版

    注意层序遍历的时候对每一层的处理方式可能不同,这里把每一层的元素保存进一个List中了,那么就需要记录每一层的数量. public List<List<Integer>> se ...

  9. C++中对象的构造顺序

    1,C++ 中的类可以定义多个对象,那么对象构造顺序是怎样的? 1,很多的 bug 是由对象的构造顺序造成的,虽然它不难: 2,对象的构造往往和构造函数牵涉在一起,构造函数的函数体又可能由非常复杂的程 ...

  10. [LeetCode] 95. 不同的二叉搜索树 II

    题目链接 : https://leetcode-cn.com/problems/unique-binary-search-trees-ii/ 题目描述: 给定一个整数 n,生成所有由 1 ... n ...