BZOJ2096: [Poi2010]Pilot

来源:互联网 发布:伪造mac ip蹭网 编辑:程序博客网 时间:2024/05/29 15:07

题目大意:给定n,k和一个长度为n的序列,求最长的最大值最小值相差不超过k的序列


题目显然是个单调队列吗...可以O(N)做....但是那段时间被我用来练习平衡树了...

从前到后扫,每扫到一个就加进来,假如发现相差超过k,就一直在平衡树中删掉队头,总时间复杂度O(NlogN).....

贴一个初期平衡树代码


#include<cstdio>  #include<cmath>  #include<iostream>  #include<cstdlib>  #define N 3000001  using namespace std;  int si[N],ti[N],rd[N],l[N],r[N],a[N],root,cnt;  int b[N];void pup(int x)  {      si[x]=si[l[x]]+si[r[x]]+ti[x];  }  void zxu(int &k)  {      int t=l[k];      l[k]=r[t];      r[t]=k;      si[t]=si[k];      pup(k);      k=t;  }  void yxu(int &k)  {      int t=r[k];      r[k]=l[t];      l[t]=k;      si[t]=si[k];      pup(k);      k=t;  }  void addadd(int &k,int x)  {      if(!k)      {          cnt++;          k=cnt;          a[cnt]=x;          si[cnt]=1;          ti[cnt]=1;          rd[cnt]=rand();          return;      }      si[k]++;      if(x==a[k])      {          ti[k]++;          return;      }      if(x<a[k])      {          addadd(l[k],x);          if(rd[l[k]]>rd[k]) zxu(k);      }      else    {          addadd(r[k],x);          if(rd[r[k]]>rd[k]) yxu(k);      }  }  void earase(int &k,int x)  {      if(!k) return;      if(a[k]==x)      {          if(ti[k]>1) ti[k]--,si[k]--;          else if(l[k]*r[k]==0) k=l[k]+r[k];          else if(rd[l[k]]>rd[r[k]])          {              zxu(k);              earase(k,x);          }          else if(rd[l[k]]<rd[r[k]])          {              yxu(k);              earase(k,x);          }          return;      }      if(x>a[k]) si[k]--,earase(r[k],x);      else if(x<a[k]) si[k]--,earase(l[k],x);  }  int rankgetnum(int k,int x)  {      if(x<=si[l[k]]) return rankgetnum(l[k],x);      if(x>si[l[k]]+ti[k]) return rankgetnum(r[k],x-si[l[k]]-ti[k]);      return a[k];  }int main()  {      int n,m,c;    cin>>c>>m;    int i,j,k,x,now=0;    int ans=0;    for(i=1;i<=m;i++)    {    now++;    scanf("%d",&b[i]);    addadd(root,b[i]);    while(rankgetnum(root,now)-rankgetnum(root,1)>c)    {    now--;    earase(root,b[i-now]);    }    ans=max(ans,now);    }    cout<<ans;}

0 0
原创粉丝点击