zoukankan      html  css  js  c++  java
  • CF13E Holes

    题目链接

    题意分析

    看这篇题解 默认你已经会LCT并且明白如何使用了

    说实在的 这题跟【P3203 [HNOI2010]弹飞绵羊】简直如出一辙

    首先 我们根据题意可以得到一棵树

    如果i+power[i]≤n的话 那么i+power[i]就是i的父亲

    否则就令n+1是i的父亲

    可以发现 n+1就是这棵树的根节点

    修改我们可以看作动态的删连边 所以就用了LCT

    至于查询的话 我们先得到从x到n+1的链

    弹了几次 就是这条链上除了n+1之外剩余点的个数 就是Splay的size

    弹走之前最后一个点 就是这条链上除了n+1之外点的最大值 我们可以使用链上最大值维护

    CODE:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #define M 1008611
    using namespace std;
    int n,m,top,fly;
    struct LCT
    {
    	int son[2],fa,siz,val,maxn;
    	bool tag;
    }tre[M];
    int power[M],sta[M];
    bool isroot(int x)
    {return !((tre[tre[x].fa].son[0]==x)||(tre[tre[x].fa].son[1]==x));}
    void pushup(int x)
    {//对于size以及最大值的维护
    	tre[x].siz=tre[tre[x].son[0]].siz+tre[tre[x].son[1]].siz+1;
    	if(tre[x].val!=fly) tre[x].maxn=max(tre[x].val,max(tre[tre[x].son[0]].maxn,tre[tre[x].son[1]].maxn));
    	else tre[x].maxn=max(tre[tre[x].son[0]].maxn,tre[tre[x].son[1]].maxn);
    }
    void down(int x)
    {
    	if(tre[x].tag)
    	{
    		if(tre[x].son[0]) tre[tre[x].son[0]].tag^=1;
    		if(tre[x].son[1]) tre[tre[x].son[1]].tag^=1;
    		tre[x].tag=0;
    		swap(tre[x].son[0],tre[x].son[1]);	
    	}
    } 
    void rotate(int x)
    {
    	int fat=tre[x].fa,fatt=tre[tre[x].fa].fa;
    	int d=(tre[tre[x].fa].son[1]==x);
    	int tson=tre[x].son[d^1];
    	if(!isroot(fat)) tre[fatt].son[tre[fatt].son[1]==fat]=x;
    	tre[x].fa=fatt;tre[x].son[d^1]=fat;tre[fat].fa=x;tre[fat].son[d]=tson;
    	if(tson) tre[tson].fa=fat;
    	pushup(fat);pushup(x);
    }
    void Splay(int x)
    {
    	int cdy=x,wzy;top=0;
    	sta[++top]=cdy;
    	while(!isroot(cdy)) sta[++top]=cdy=tre[cdy].fa;
    	while(top>0) down(sta[top--]);
    	while(!isroot(x))
    	{
    		cdy=tre[x].fa;wzy=tre[tre[x].fa].fa;
    		if(!isroot(cdy))
    		{
    			if((tre[cdy].son[1]==x)^(tre[wzy].son[1]==cdy)) rotate(x);
    			else rotate(cdy);
    		}
    		rotate(x);
    	}
    	pushup(x);
    }
    void access(int x)
    {
    	for(int now=0;x;x=tre[now=x].fa)
    	{
    		Splay(x);tre[x].son[1]=now;pushup(x);
    	}
    }
    void makeroot(int x)
    {
    	access(x);Splay(x);tre[x].tag^=1;
    }
    void split(int x,int y)
    {
    	makeroot(x);access(y);Splay(y);;
    }
    void link(int x,int y)
    {
    	makeroot(x);
    	tre[x].fa=y; 
    }
    void cut(int x,int y)
    {
    	split(x,y);
    	tre[x].fa=tre[y].son[0]=0;
    	return;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);fly=n+1;//fly就是所有飞出去的到达的位置 
    	for(int i=1;i<=n;++i) scanf("%d",&power[i]),tre[i].val=i;
    	for(int i=1;i<=n;++i)
    	{
    		int x=i,y=min(fly,i+power[i]);
    		link(x,y);
    	}
    	for(int i=1,knd,x,y;i<=m;++i)
    	{
    		scanf("%d",&knd);
    		if(knd==0)
    		{
    			scanf("%d%d",&x,&y);
    			int fro=min(fly,x+power[x]),to=min(fly,x+y);
    			cut(x,fro);link(x,to);
    			power[x]=y;
    		}
    		else
    		{
    			scanf("%d",&x);
    			makeroot(x);
    			access(fly);
    			Splay(fly);
    			printf("%d %d
    ",tre[fly].maxn,tre[fly].siz-1);
    		}
    		
    	}
    	return 0;
    }
    
  • 相关阅读:
    面向对象、面向接口、面向方法编程的区别?
    面向接口、对象、方面编程区别 -- 精简版
    面向接口编程详解(一)——思想基础
    吴裕雄--天生自然数据结构:静态链表及其创建
    吴裕雄--天生自然数据结构:单链表的基本操作
    吴裕雄--天生自然数据结构:单链表,链式存储结构
    吴裕雄--天生自然数据结构:顺序表的基本操作
    吴裕雄--天生自然Python Matplotlib库学习笔记:matplotlib绘图(2)
    吴裕雄--天生自然Python Matplotlib库学习笔记:matplotlib绘图(1)
    吴裕雄--天生自然Numpy库学习笔记:NumPy Matplotlib
  • 原文地址:https://www.cnblogs.com/LovToLZX/p/14323046.html
Copyright © 2011-2022 走看看