【BZOJ】【2002】【HNOI2010】弹飞绵羊

呃这题的Hint写着splay启发式合并……但是蒟蒻不懂T_T只好写个简单的LCT来蒙混过关,就是时间效率上差劲的很……

不过能够一次AC心情也是蛮愉悦的~

  1 /**************************************************************
  2     Problem: 2002
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:1932 ms
  7     Memory:6156 kb
  8 ****************************************************************/
  9
 10 //BZOJ 2002
 11 #include<cstdio>
 12 #include<cstdlib>
 13 #include<cstring>
 14 #include<iostream>
 15 #include<algorithm>
 16 #define rep(i,n) for(int i=0;i<n;++i)
 17 #define F(i,j,n) for(int i=j;i<=n;++i)
 18 #define D(i,j,n) for(int i=j;i>=n;--i)
 19 using namespace std;
 20 const int N=200010;
 21
 22 int c[N][2],fa[N],size[N],n,m,k[N],st[N],top=0;
 23 bool rev[N];
 24
 25 int read(){
 26     char ch=getchar();
 27     int sig=1,tmp=0;
 28     while(ch<‘0‘||ch>‘9‘) {if (ch==‘-‘) sig=-1;ch=getchar();}
 29     while(ch>=‘0‘ && ch<=‘9‘) {tmp=10*tmp+ch-‘0‘;ch=getchar();}
 30     return tmp*sig;
 31 }
 32
 33 void Push_down(int x){
 34     if (rev[x]){
 35         rev[x]^=1; rev[c[x][0]]^=1; rev[c[x][1]]^=1;
 36         swap(c[x][0],c[x][1]);
 37     }
 38 }
 39 inline void Push_up(int x){
 40     size[x]=size[c[x][0]]+size[c[x][1]]+1;
 41 }
 42 bool isroot(int x){
 43     return c[fa[x]][0]!=x && c[fa[x]][1]!=x;
 44 }
 45 void rotate(int x){
 46     int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
 47     if (!isroot(y)) c[z][c[z][1]==y]=x;
 48     fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
 49     c[y][l]=c[x][r]; c[x][r]=y;
 50     Push_up(y); Push_up(x);
 51 }
 52 void splay(int x){
 53     top=0; st[top++]=x;
 54     for(int i=x;!isroot(i);i=fa[i])
 55         st[top++]=fa[i];
 56     while(top--) Push_down(st[top]);
 57
 58     while(!isroot(x)){
 59         int y=fa[x],z=fa[y];
 60         if (!isroot(y)){
 61             if (c[y][0]==x^c[z][0]==y) rotate(x);
 62             else rotate(y);
 63         }
 64         rotate(x);
 65     }
 66 }
 67 void access(int x){
 68     for(int t=0;x;t=x,x=fa[x])
 69         splay(x),c[x][1]=t,Push_up(x);
 70 }
 71 void makeroot(int x){
 72     access(x); splay(x); rev[x]^=1;
 73 }
 74 int find(int x){
 75     access(x); splay(x);
 76     while(c[x][0]) x=c[x][0];
 77     return x;
 78 }
 79 void cut(int x,int y){
 80     makeroot(x); access(y); splay(y);
 81     if (c[y][0]==x) c[y][0]=fa[x]=0;
 82 }
 83 void link(int x,int y){
 84     makeroot(x); fa[x]=y;
 85 }
 86 //LCT end
 87 int main(){
 88 //  freopen("input.txt","r",stdin);
 89     n=read();
 90     F(i,1,n){
 91         k[i]=read();
 92         link(i,min(i+k[i],n+1));
 93     }
 94     m=read();
 95     int x,y,z;
 96     F(i,1,m){
 97         x=read(); y=read(); y++;
 98         if (x==1) {
 99             makeroot(n+1);
100             access(y);splay(y);
101             printf("%d\n",size[y]-1);
102         }
103         else if(x==2){
104             z=read();
105             cut(y,min(y+k[y],n+1));
106             k[y]=z;
107             link(y,min(y+k[y],n+1));
108         }
109     }
110     return 0;
111 }

时间: 2024-10-11 00:13:55

【BZOJ】【2002】【HNOI2010】弹飞绵羊的相关文章

BZOJ 2002 HNOI2010 弹飞绵羊 分块

题目大意及LCT版本题解:见 http://blog.csdn.net/popoqqq/article/details/38849471 今天手滑用分块又重写了一遍这道题0.0 分块就是短啊 将弹簧分为√n块 对于每个弹簧 我们记录一下从这个弹簧出发直到弹到块外为止的弹跳次数及落点 查询沿着落点弹到出去为止 修改从块开始到这个点为止修改一遍 这样修改和查询都是O(√n)的 #include<cmath> #include<cstdio> #include<cstring>

bzoj 2002 Bounce 弹飞绵羊(分块)

2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 11202  Solved: 5698[Submit][Status][Discuss] Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹k

BZOJ 2002 Bounce 弹飞绵羊(分块|暴力|)(困难)

Bounce 弹飞绵羊 Time Limit:10000MS     Memory Limit:265216KB     64bit IO Format:%lld & %llu Submit Status Practice HYSBZ 2002 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后

【bzoj 2002】弹飞绵羊

Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞.绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞.为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数. Input 第一行

BZOJ 2002 HNOI2010 弹飞羊 块

标题效果,LCT解释版本:见 http://blog.csdn.net/popoqqq/article/details/38849471 如今,用一只手滑动块,并再次改写这个问题0.0 块短啊 将进入春天√n片 对于每一个弹簧的 我们记录一下从这个弹簧出发直到弹到块外为止的弹跳次数及落点 查询沿着落点弹到出去为止 改动从块開始到这个点为止改动一遍 这样改动和查询都是O(√n)的 #include<cmath> #include<cstdio> #include<cstring

HNOI2010 弹飞绵羊

codevs 2333 弹飞绵羊 http://codevs.cn/problem/2333/ 2010年省队选拔赛湖南 题目描述 Description Lostmonkey发明了一种超级反弹装置.为了在绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿一条直线摆放 n个反弹装置,并按从前往后的方式将反弹装置依次编号为 0 到 n-1,对 0≤i≤n-1,为第 i 个反弹装置设定了初始弹力系数 ki,当绵羊落到第 i 个反弹装置上时,它将被往后弹出 ki 步,

Hnoi2010弹飞绵羊题解LCT

题目大意 给定一个序列,每个点有一个权值a[i],一只绵羊若站在点i上会被弹到第i+a[i]个点上,支持单点修改操作,求从某个点出发经过多少次会被弹飞. 题解 令每个点的父亲结点是会被弹到的结点,那询问时每个点的答案就是这个点的深度. LCT维护size域即可 一开始以为是有向树,后来发现自己犯2了,按无向的做法就可以. 做这种题千万别手残.我因为一句x->rever()打成x->rev^=1,就有了如下结果,调了快一整天了! Code #include <cstdio> #inc

洛谷P3203 [HNOI2010]弹飞绵羊【LCT】

题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞.绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞.为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数. 输入格式: 第一行包含一个整数n

HNOI2010弹飞绵羊(块状数组)

不得不说块状数组好神奇的啊!这道题的标签可是splay的启发是合并(什么高大上的东西),竟然这么轻松的就解决了! var x,y,i,j,tot,n,m,ch:longint; f,k,l,bl,go:array[0..200100] of longint; procedure init; begin readln(n); x:=trunc(sqrt(n));j:=x; for i:=1 to n do begin if j=x then begin j:=1;inc(tot);l[tot]:=

BZOJ2002 HNOI2010 弹飞绵羊 LCT

LCT=树链剖分+平衡树(多用Splay),AC之后才对这个等式深有感触-- 我们定义一个操作Access(x),这个操作可以将从x到根节点路径上的所有节点放到一颗Splay里,一切操作都在这棵Splay里做.你说要维护任意两个点的路径?反正是无向树换一下根不就好了-- 我们以执行Access的顺序为权值来进行树链剖分,每一条链用一颗Splay按照深度来维护,每一颗Splay与他的父亲(由于一条链一定是在一个点u的子树上,所以我们只需要让这颗Splay的根与u相连就好,无所谓根和u在原树中是否相