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$了. 由 ...
随机推荐
- jenkins中通过Publish Over SSH将项目部署到远程机器上
Publish Over SSH插件使用在使用Publish Over SSH之前,需要制作SSH私钥.机器间做免密登录配置.假设机器A,ip为192.168.AA.AAA,机器B: 192.168. ...
- 练习1:python设计停车入库出库系统
前言: 最近在某个测试群看到有人抛出了一个面试题.为了提升自己的编程能力,我也尝试的用python去写了一下. 语言:python,数据库:sqlite .菜鸟来袭,只是基本实现功能,可能没有考虑太 ...
- Django-DRF组件学习-视图学习
1.请求与响应 drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. Djan ...
- 20191127 Spring Boot官方文档学习(5)
5.Spring Boot Actuator:可投入生产的功能 Spring Boot包含许多其他功能,可帮助您在将应用程序投入生产时监控和管理您的应用程序.您可以选择使用HTTP端点或JMX管理和监 ...
- 第二章 Git
1.安装 这个就不必细说了 2.安装完后还要进行一步设置. 在命令行输入: git config --global user.name "Your Name" git config ...
- spring - 第N篇 一些笔记
1.properties文件的引入 <bean id="propertyConfigurer" class="org.springframework.beans.f ...
- 微信JSSdk实现分享功能
1. 概述 微信分享服务器的作用是为用户在微信浏览器端对来自网站以及客户端的页面进行二次分享链接时更友好的展示提供服务.为实现二次分享功能需要使用微信JS-SDK来开发. 微信JS-SDK是微信公众平 ...
- 搜索专题: HDU1026Ignatius and the Princess I
Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- app接口开发
最近一段时间一直在做APP接口,总结一下APP接口开发过程中的注意事项: 1.效率:接口访问速度 APP有别于WEB服务,对服务器端要求是比较严格的,在移动端有限的带宽条件下,要求接口响应速度要快,所 ...
- PHP MVC结构系统架构设计
今天研究了下PHP MVC结构,所以决定自己写个简单的MVC,以待以后有空再丰富.至于什么MVC结构,其实就是三个Model,Contraller,View单词的简称,,Model,主要任务就是把数据 ...