zoukankan      html  css  js  c++  java
  • 洛谷P3434 [POI2006]KRA-The Disks(线段树)

    洛谷题目传送门
    (O(n))的正解算法对我这个小蒟蒻真的还有点思维难度。洛谷题解里都讲得很好。
    考试的时候一看到300000就直接去想各种带log的做法了,反正不怕T。。。。。。
    我永远只会有最直观的思路(最差的程序效率
    题目相当于每次让我们找区间([1,las-1])中上数第一个比当前盘子半径小的位置(las为上一次盘子掉到的位置)于是用线段树无脑搞一下,维护区间最小值,每次找这个位置,能往左跳就往左,不能的话再往右,当然如果超过了las-1就不用找了,直接放在las上面(相当于las--)直到全部放完或las=0为止。

    #include<cstdio>
    #define R register int
    #define lc u<<1
    #define rc u<<1|1
    #define G c=getchar()
    #define min2(x,y) x<y?x:y
    #define in(z) G;
    	while(c<'-')G;
    	z=c&15;G;
    	while(c>'-')z*=10,z+=c&15,G
    const int N=300009,M=10000009;
    int las,k,a[N],mina[M];//mina记录最小值
    void build(R u,R l,R r){
    	if(l==r){
    		mina[u]=a[l];
    		return;
    	}
    	R m=(l+r)>>1;
    	build(lc,l,m);build(rc,m+1,r);
    	mina[u]=min2(mina[lc],mina[rc]);
    }
    int ask(R u,R l,R r){
    	if(l==r)return l-1;
    	R m=(l+r)>>1;
        //因为要找位置最靠前的,所以优先往左
    	if(mina[lc]<k)return ask(lc,l,m);
    	if(m<las-1&&mina[rc]<k)return ask(rc,m+1,r);//m要小于las-1
    	return las-1;
    }
    int main(){
    	R n,m;
    	register char c;
    	in(n);in(m);las=n+1;
    	for(R i=1;i<=n;++i){in(a[i]);}
    	build(1,1,n);
    	while(m--&&las){//las=0直接就不放了
    		in(k);
    		las=ask(1,1,n);
    	}
    	printf("%d
    ",las);
    	return 0;
    }
    
  • 相关阅读:
    HDU1720 A+B Coming
    HDU1390 ZOJ1383 Binary Numbers
    HDU1390 ZOJ1383 Binary Numbers
    HDU2504 又见GCD
    HDU2504 又见GCD
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1020 ZOJ2478 Encoding
    HDU1020 ZOJ2478 Encoding
    HDU2097 Sky数
  • 原文地址:https://www.cnblogs.com/flashhu/p/8465968.html
Copyright © 2011-2022 走看看