zoukankan      html  css  js  c++  java
  • 题解 CF13E 【Holes】

    这个题和$P3203 $弹飞绵羊基本上完全一致

    我的做法是用(LCT)维护信息,开一个节点(fly),表示到此节点时,小球会弹飞,那么查询弹多少次即为(siz[fly]-1)

    最后一次落在哪个洞可以用维护链上最大值来解决

    一些小细节看代码就行了

    (code:)

    #include<bits/stdc++.h>
    #define maxn 400010
    using namespace std;
    template<typename T> inline void read(T &x)
    {
    	x=0;char c=getchar();bool flag=false;
    	while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	if(flag)x=-x;
    }
    int n,m,flag,root,tot,fly;
    int p[maxn],fa[maxn],ch[maxn][2],siz[maxn],ma[maxn],rev[maxn];
    bool check(int x)
    {
    	return ch[fa[x]][1]==x;
    }
    void pushr(int x)
    {
    	rev[x]^=1;swap(ch[x][0],ch[x][1]);
    }
    void pushup(int x)
    {
    	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
    	if(x!=fly) ma[x]=max(x,max(ma[ch[x][0]],ma[ch[x][1]]));
    	else ma[x]=max(ma[ch[x][0]],ma[ch[x][1]]);
    }
    void pushdown(int x)
    {
    	if(!rev[x]) return;
    	pushr(ch[x][0]),pushr(ch[x][1]);
    	rev[x]=0;
    }
    bool notroot(int x)
    {
    	return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
    }
    void rotate(int x)
    {
    	int y=fa[x],z=fa[y],k=check(x),w=ch[x][k^1];
    	if(notroot(y)) ch[z][check(y)]=x;
    	fa[x]=z;
    	ch[y][k]=w;
    	if(w) fa[w]=y;
    	ch[x][k^1]=y;
    	fa[y]=x;
    	pushup(y);
    }
    void all(int x)
    {
    	if(notroot(x)) all(fa[x]);
    	pushdown(x);
    }
    void splay(int x)
    {
    	all(x);
    	for(int y;notroot(x);rotate(x))
    		if(notroot(y=fa[x]))
    			rotate(check(x)^check(y)?x:y);
    	pushup(x);
    }
    void access(int x)
    {
    	for(int y=0;x;y=x,x=fa[x])
    		splay(x),ch[x][1]=y;
    }
    void makeroot(int x)
    {
    	access(x),splay(x),pushr(x);
    }
    void split(int x,int y)
    {
    	makeroot(x),access(y),splay(y);
    }
    void link(int x,int y)
    {
    	split(x,y),fa[x]=y;
    }
    void cut(int x,int y)
    {
    	split(x,y),fa[x]=ch[y][0]=0;
    }
    int main()
    {
    	read(n),read(m);
    	fly=n+1;
    	for(int i=1;i<=n;++i)
    	{
    		read(p[i]);
    		if(i+p[i]<=n) link(i,i+p[i]);
    		else link(i,fly);
    	}
    	while(m--)
    	{
    		int x,y;
    		read(flag);
    		if(flag)
    		{
    			read(x);
    			split(x,fly);
    			printf("%d %d
    ",ma[fly],siz[fly]-1);
    		}
    		else
    		{
    			read(x),read(y);
    			if(x+p[x]<=n) cut(x,x+p[x]);
    			else cut(x,fly);
    			p[x]=y;
    			if(x+p[x]<=n) link(x,x+p[x]);
    			else link(x,fly);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    MyBatisPartA
    概念:漏洞扫描技术
    概念:防火墙技术
    概念:认证技术与访问控制
    概念:为什么要引进密钥管理技术
    概念:数字签名、传统签名和认证
    概念:简述对称密码算法和公钥密码算法的区别
    概念:单向散列函数部分知识点
    Redis单线程QPS效率高的原因,以及redis6.0升级后的变化
    Mydql数据库缓存池Buffer Pool 冷热数据分离
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229813.html
Copyright © 2011-2022 走看看