题解 P3434 【[POI2006]KRA-The Disks】

oscar

2017-09-27 21:44:19

Solution

【POI补全计划#18 POI2006 KRA】 水到随便做的一道题,然而我的做法还是比楼下题解的做法多个log。。。 直觉上二分肯定能过,就没仔细想线性做法 预处理出管道的每个格子上方最小的半径,将该格子的半径设置为最细的那个,位置0的半径设为足够大的数(正确性:通不过上面的部分就到不了这个格子)(作用:方便二分) 然后每次记录上一个盘子掉到的位置x,在0和x之间查找比盘子半径大的最靠下的位置,若查到x则往上摞一个盘子,若查到0则说明后面的盘子都放不进去,其余情况正常处理就好了.... 贴代码: ```cpp #include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int MAXN=300010; int siz[MAXN],n,m; int main() { scanf("%d%d",&n,&m); siz[0]=0x3f3f3f3f; for(int i=1;i<=n;i++) { scanf("%d",&siz[i]); if(siz[i]>siz[i-1])siz[i]=siz[i-1]; } int tmp,cur=n; for(int i=1;i<=m;i++) { scanf("%d",&tmp); int l=0,r=cur; while(l<r) { int mid=(l+r+1)/2; if(siz[mid]<tmp)r=mid-1; else l=mid; } if(l==cur)cur--; else cur=l; if(cur==0)break; } printf("%d\n",cur); return 0; } ```