码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 3827: [Poi2014]Around the world

时间:2016-09-10 23:53:35      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:

Sol

并查集.

一个点所能到达的最远是单调不降的.然后将链延长到两倍,预处理出每个点到达的最远点,然后倒着计算深度.

再然后一直跳,跳到>=x+n的点,因为跳到的点都能到最终的点,并且不影响后面的答案.

Code

/**************************************************************
    Problem: 3827
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:70156 ms
    Memory:20820 kb
****************************************************************/
 
#include<cstdio>
#include<cstring>
#include<iostream>
 
using namespace std;
 
const int N = 1000005;
const int INF = 0x3fffffff;
 
int n,m,s,lim,ans;
int a[N],nxt[N<<1],d[N<<1];
 
inline int in(int x=0,char ch=getchar()){ while(ch>‘9‘||ch<‘0‘) ch=getchar();
    while(ch>=‘0‘&&ch<=‘9‘) x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar();return x; }
 
int DFS(int x){
    int ff=x;
    for(;ff<x+n;ff=nxt[ff]);
    for(int u=x,v=nxt[x];v!=ff;u=v,v=nxt[v]) nxt[u]=ff;
    return d[x]-d[ff];
}
int main(){
//  freopen("in.in","r",stdin);
    n=in(),s=in(),m=n<<1|1;
    for(int i=1;i<=n;i++) a[i]=in(),lim=max(lim,a[i]);
    for(int i=1,x;i<=s;i++){
        x=in();ans=INF;
        if(x<lim){ puts("NIE");continue; }
        for(int u=1,v=1,t=0;u<=m;u++){
            while(v<m&&t+a[v>n?v-n:v]<=x)
            t+=a[v>n?v-n:v],v++;
            nxt[u]=v,t-=a[u>n?u-n:u];
        }
        for(int i=m;i;i--) d[i]=d[nxt[i]]+1;
//      for(int i=1;i<=m;i++) cout<<nxt[i]<<" ";cout<<endl;
//      for(int i=1;i<=m;i++) cout<<d[i]<<" ";cout<<endl;
         
        for(int i=1;i<=n;i++) ans=min(ans,DFS(i));
        cout<<ans<<endl;
    }return 0;
}

  

BZOJ 3827: [Poi2014]Around the world

标签:

原文地址:http://www.cnblogs.com/beiyuoi/p/5860420.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!