BZOJ3141: [Hnoi2013]旅行

来源:互联网 发布:java培训好不好 编辑:程序博客网 时间:2024/06/14 06:47

很厉害的一题
我尝试写过题解发现写的很不清楚所以还是不写了膜题解吧
题解1
题解2


code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;void down(int &x,int y){if(x>y)x=y;}void up(int &x,int y){if(x<y)x=y;}void read(int &x){    char c;    while(!((c=getchar())>='0'&&c<='9'));    x=c-'0';    while((c=getchar())>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0';}const int maxn = 510000;struct node{    int x,pre,nex;    node(){}    node(int _x,int _pre,int _nex){x=_x;pre=_pre;nex=_nex;}}a[maxn<<2]; int head[maxn<<1],tail[maxn<<1],len;int id[maxn],c[maxn],s[maxn];void ins(int ans,int n,int m,int S,int i){    int k=s[i+1];    if(ceil((double)abs(S-k)/(m-1))<=ans)    {        if(!tail[n+k])        {            a[++len]=node(i,0,0);            head[n+k]=tail[n+k]=len;        }        else        {            a[++len]=node(i,tail[n+k],0);            a[tail[n+k]].nex=len;            tail[n+k]=len;            int nw=len;            while(a[nw].pre)            {                int p=a[nw].pre;                if(id[a[p].x]<id[a[nw].x]) break;                if(a[p].pre) a[a[p].pre].nex=nw;                else head[n+k]=len;                a[nw].pre=a[p].pre;            }        }    }}int n,m;int re[maxn],nr;int main(){    read(n); read(m);    for(int i=1;i<=n;i++)    {           read(id[i]),read(c[i]);        if(!c[i]) c[i]=-1;    }    if(m==1) {printf("%d\n",id[n]); return 0;}    int l=0;    for(int i=n;i>=1;i--)     {        s[i]=s[i+1]+c[i];        if(s[i]==0) l++;    }    int ans;    if(s[1]==0)    {        if(l>=m) ans=0;        else ans=1;    }    else ans=ceil(double(abs(s[1]))/double(m));    if(!ans)    {        l--;        int he=1,ta=0;        for(int i=1;i<=n;i++)            if(s[i+1]==0)            {                re[++ta]=i; l--;                while(he<ta&&id[re[ta-1]]>id[re[ta]]&&ta-he+l>=m)                    re[ta-1]=re[ta],ta--;            }        for(int i=he;i<=he+m-2;i++) printf("%d ",id[re[i]]);        printf("%d\n",id[n]);        return 0;    }    int S=s[1];    for(int i=1;i<=n-m+1;i++)        ins(ans,n,m,S,i);    int lax=0; S=s[1]; nr=0;    for(int i=1;i<m;i++)    {        int mn=INT_MAX,mnx;        for(int j=n+S-ans;j<=n+S+ans;j++)        {            if(ceil((double)abs(j-n)/double(m-i))>ans) continue;            while(head[j])            {                if(a[head[j]].x<=lax)                {                    if(head[j]==tail[j]) head[j]=tail[j]=0;                    else                    {                        a[a[head[j]].nex].pre=0;                        head[j]=a[head[j]].nex;                    }                }                else break;            }            if(head[j])             {                if(mn>id[a[head[j]].x])                     mn=id[a[head[j]].x],mnx=a[head[j]].x;            }        }        re[++nr]=mn;        S=s[mnx+1];        lax=mnx;        if(n-m+i+1<n)            ins(ans,n,m-i,S,n-m+i+1);    }    re[++nr]=id[n];    for(int i=1;i<nr;i++) printf("%d ",re[i]);    printf("%d\n",re[nr]);    return 0;}
0 0
原创粉丝点击