2017 多校训练第二场 HDU 6047 Maximum Sequence

来源:互联网 发布:视觉对位系统算法 编辑:程序博客网 时间:2024/05/16 08:04

这一题真是累死我了,比赛的时候搞了一个树状数组结果TLE,最后还是队友写了一个线段树才过的,不就是树状数组多了一个logn嘛TAT,还有的大佬要是再卡一个常数,线段树可能都过不了TAT

等到下来补题的时候,单调队列不懂怎么做TAT,就开始搞线段树,我觉得写得很对啊怎么又错了TAT,好吧换一种写法,看到有一种优先队列的写法,正确性自己想了想就写了,然后交上去还是错的TAT,怎么回事啊啊啊啊啊TAT

然后发现我预编译的东西没删掉,所以一直打开的是测试文件TAT

心好痛TAT,我怎么这么菜啊TAT

优先队列版本:

#include <bits/stdc++.h>using namespace std;// #define test TEST #define lson l,m,rt*2#define rson m+1,r,rt*2+1typedef long long ll;const int mod=1e9+7;const int maxn=250005;int a[maxn<<1],b[maxn],bucket[maxn];int n;// int que[maxn],Max[maxn],pos[maxn];void bucketsort(int vv){memset(bucket,0,sizeof(bucket));for(int i=0;i<n;i++){bucket[b[i]]++;}for(int i=0,j=0;i<=vv;i++){while(bucket[i]){b[j++]=i;bucket[i]--;}}}typedef struct Node{int id,val;bool operator < (const Node &x) const {if(val!=x.val) return val<x.val;else return id>x.id;}}node;int main(int argc, char const *argv[]){#ifdef test freopen("test.txt","r",stdin);#endif while(~scanf("%d",&n)){node temp;priority_queue<node>que;for(int i=1;i<=n;i++){scanf("%d",&a[i]);temp.id=i,temp.val=a[i]-i;que.push(temp);}int vv=0;for(int i=0;i<n;i++){scanf("%d",&b[i]);vv=max(vv,b[i]);}bucketsort(vv);//桶排for(int i=n+1;i<=n+n;i++){temp=que.top();while(b[i-n-1]>temp.id){que.pop();temp=que.top();}a[i]=temp.val;temp.id=i,temp.val=a[i]-i;que.push(temp);}int ans=0;for(int i=n+1;i<=n+n;i++){ans=(ans+a[i])%mod;}printf("%d\n",ans);}return 0;}

线段树版本:

#include <bits/stdc++.h>using namespace std;//#define test TEST #define lson l,m,rt*2#define rson m+1,r,rt*2+1typedef long long ll;const int mod=1e9+7;const int maxn=250005;int a[maxn<<1],b[maxn],bucket[maxn];int n;// int que[maxn],Max[maxn],pos[maxn];void bucketsort(int vv){    memset(bucket,0,sizeof(bucket));    for(int i=0;i<n;i++){        bucket[b[i]]++;    }    for(int i=0,j=0;i<=vv;i++){        while(bucket[i]){            b[j++]=i;            bucket[i]--;        }    }}typedef struct Node{    int id,val;    bool operator < (const Node &x) const {        if(val!=x.val) return val<x.val;        else return id>x.id;    }}node;int main(int argc, char const *argv[]){    #ifdef test     freopen("test.txt","r",stdin);    #endif     while(~scanf("%d",&n)){        node temp;        priority_queue<node>que;        for(int i=1;i<=n;i++){            scanf("%d",&a[i]);            temp.id=i,temp.val=a[i]-i;            que.push(temp);        }        int vv=0;        for(int i=0;i<n;i++){            scanf("%d",&b[i]);            vv=max(vv,b[i]);        }        bucketsort(vv);//桶排        for(int i=n+1;i<=n+n;i++){            temp=que.top();            while(b[i-n-1]>temp.id){                que.pop();                temp=que.top();            }            a[i]=temp.val;            temp.id=i,temp.val=a[i]-i;            que.push(temp);        }        int ans=0;        for(int i=n+1;i<=n+n;i++){            ans=(ans+a[i])%mod;        }        printf("%d\n",ans);    }        return 0;}

再贴一份别人家的单调队列代码:

#include<cstdio>  #include<cmath>  #include<cstring>  #include<algorithm>  #include<iostream>    using namespace std;  #define LL long long  const int mod = 1e9+7;  const int maxn = 250010;  int n;  int a[maxn];  int b[maxn];  struct Node{      int id;      int val;  };  Node q[maxn<<1];    int main()  {      while( ~scanf("%d",&n))      {          int head = 0;          int tail = 0;          for( int i = 1; i <= n; i++)          {              scanf("%d",&a[i]);              if( tail == 0)              {                  q[tail].id = i;                  q[tail++].val = a[i]-i;              }              else              {                  while( head < tail && a[i]-i >= q[tail-1].val)                      tail--;                  q[tail].id = i;                  q[tail++].val = a[i]-i;              }          }          for( int i = 1; i <= n; i++)              scanf("%d",&b[i]);          sort(b+1,b+1+n);            int p = 1;          Node tmp;          LL ans = 0;          while( p <= n)          {              while( b[p] > q[head].id)                  head++;              ans = (ans+q[head].val)%mod;              tmp.id = p+n;              tmp.val = q[head].val-(n+p);              while( head < tail && tmp.val >= q[tail-1].val)                  tail--;              q[tail++] = tmp;              p++;          }          printf("%lld\n",ans);        }        return 0;  }  



原创粉丝点击