CodeForces6E st查询

来源:互联网 发布:windows 远程桌面 软件 编辑:程序博客网 时间:2024/04/29 13:28
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>using namespace std;const int maxn= 200010;const int maxn2=8000000;int n,a[maxn],mx[maxn][20],mn[maxn][20],ql[maxn],qr[maxn];/*struct Node{    int l,r;    int lenth;}node[maxn2];*////用结构体数组会MLE,起码开到10^10次方void init(){int m=floor(log((double)n)/log(2.0));for(int i=1;i<=n;i++) mx[i][0]=mn[i][0]=a[i];for(int i=1;i<=m;i++)for(int j=n;j>0;j--){mx[j][i]=mx[j][i-1];mn[j][i]=mn[j][i-1];if(j+(1<<(i-1))<=n){mx[j][i]=max(mx[j][i],mx[j+(1<<(i-1))][i-1]);mn[j][i]=min(mn[j][i],mn[j+(1<<(i-1))][i-1]);//cout<<"mx:"<<mx[j][i]<<"mn:"<<mn[j][i]<<endl;}}}/*bool cmp1(const Node &a,const Node &b){    return a.lenth>b.lenth;}*/int query(int l,int r){int m=floor(log((double)(r-l+1))/log(2.0));int Max=max(mx[l][m],mx[r-(1<<m)+1][m]);int Min=min(mn[l][m],mn[r-(1<<m)+1][m]);//cout<<"1:"<<mx[l][m]<<"2:"<<mx[r-(1<<m)+1][m]<<endl;//cout<<"m:"<<Max<<"mi:"<<Min<<endl;return Max-Min;}int main(){   int k,maxs,cnt,flag,ans;    while(scanf("%d%d",&n,&k)!=EOF)    {        cnt=0;        ans=0;        //memset(node,0,sizeof(node));        memset(a,0,sizeof(a));        memset(mx,0,sizeof(mx));        memset(mn,0,sizeof(mn));        for(int k=1;k<=n;k++)            scanf("%d",&a[k]);        init();        int i;        int j; for(i=j=1;j<=n;i++)        {            if(j<i)                j=i;            while(j<=n&&query(i,j)<=k)///遍所有可能区间尽量不要用嵌套for循环,会炸掉                ++j;            if(j-i>ans)                ans=j-i,ql[0]=i,qr[0]=j-1,flag=1;            else if(j-i==ans)                ql[flag]=i,qr[flag++]=j-1;        }///以上这种遍历方法值得学习,虽然写得多的但是复杂度大大减少,不能偷懒!        //sort(node+1,node+num,cmp1);        //maxs=node[1].lenth;        //cout<<"ma:"<<maxs<<endl;        /*if(maxs==1)            printf("2 ");        else*/            printf("%d %d\n",ans,flag);        /*for(int i=1;i<num;i++)        {            if(node[i].lenth==maxs)            {                cnt++;            }        }        printf("%d\n",cnt);*/        for(int i=0;i<flag;i++)            printf("%d %d\n",ql[i],qr[i]);            }            return 0;    }


整体思路比较简单清晰,但是需要注意细节上的算法优化。

1、遇到大数据时尽量不要用结构体数组,改用两个数组来存储。

2、区间的遍历尽量不要用嵌套for。

原创粉丝点击