hdu4630&&hdu4638 线段树离线操作

来源:互联网 发布:淘宝描述不符被下架 编辑:程序博客网 时间:2024/06/16 07:32

两题都是朴素想法枚举两个端点O(n^2)超时,那么枚举其中一个端点用线段树维护另一个端点。关键在于没插入一个端点后都是成段更新,否则又会退化到O(N^2)。

ps:两题用c++交都比g++快500ms以上。

4630

//#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1const int maxn=50005;int tree[maxn<<2],lz[maxn<<2];void pushdown(int rt){    tree[rt]=max(tree[rt],lz[rt]);    lz[rt<<1]=max(lz[rt<<1],lz[rt]);    lz[rt<<1|1]=max(lz[rt<<1|1],lz[rt]);    lz[rt]=-1;}void update(int L,int R,int val,int l,int r,int rt){    if(L<=l&&r<=R)    {        lz[rt]=max(lz[rt],val);        return ;    }    int mid=(l+r)>>1;    if(R<=mid)    {        pushdown(rt);        update(L,R,val,lson);        tree[rt]=max(tree[rt<<1],lz[rt<<1]);        tree[rt]=max(tree[rt],max(tree[rt<<1|1],lz[rt<<1|1]));        return ;    }    if(L>mid)    {        pushdown(rt);        update(L,R,val,rson);        tree[rt]=max(tree[rt<<1],lz[rt<<1]);        tree[rt]=max(tree[rt],max(tree[rt<<1|1],lz[rt<<1|1]));        return ;    }    pushdown(rt);    update(L,R,val,lson);    update(L,R,val,rson);    tree[rt]=max(tree[rt<<1],lz[rt<<1]);    tree[rt]=max(tree[rt],max(tree[rt<<1|1],lz[rt<<1|1]));}int query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)    {        return max(tree[rt],lz[rt]);    }    int mid=(l+r)>>1;    pushdown(rt);    if(R<=mid)    {        return query(L,R,lson);    }    if(L>mid)    {        return query(L,R,rson);    }    return max(query(L,R,lson),query(L,R,rson));}int a[maxn];struct qyy{    int l,r,id;    qyy(){}    qyy(int a,int b,int c)    {        l=a;r=b;id=c;    }    bool operator< (const qyy &a) const    {        return r<a.r;    }}qy[maxn];int qcnt;struct opt{    int ans,id;    opt(){}    opt(int a,int b)    {        ans=a;id=b;    }    bool operator< (const opt &a) const    {        return id<a.id;    }}opt[maxn];int ocnt;int pre[maxn];int main(){    int t,n,m,i,j,l,r,cnt;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i=1;i<=n;++i)        {            scanf("%d",&a[i]);        }        scanf("%d",&m);        qcnt=0;ocnt=0;        for(i=1;i<=m;++i)        {            scanf("%d%d",&l,&r);            if(l==r)            {                opt[ocnt].ans=0;                opt[ocnt++].id=i;            }            else            {                qy[qcnt].id=i;                qy[qcnt].l=l;                qy[qcnt++].r=r;            }        }        sort(qy,qy+qcnt);        memset(pre,-1,sizeof(pre));        memset(tree,-1,sizeof(tree));        memset(lz,-1,sizeof(lz));        cnt=0;        for(i=1;i<=n;++i)        {            for(j=1;j*j<=a[i];++j)            {                if(a[i]%j!=0)                    continue;                if(pre[j]!=-1)                {                    update(1,pre[j],j,1,n,1);                }                if(pre[a[i]/j]!=-1)                {                    update(1,pre[a[i]/j],a[i]/j,1,n,1);                }                pre[j]=i;                pre[a[i]/j]=i;            }            while(cnt<qcnt&&qy[cnt].r==i)            {                opt[ocnt].id=qy[cnt].id;                opt[ocnt++].ans=query(qy[cnt].l,qy[cnt].l,1,n,1);                cnt++;            }            if(cnt==qcnt)                break;        }        sort(opt,opt+m);        for(i=0;i<m;++i)        {            printf("%d\n",opt[i].ans);        }    }    return 0;}


4638

//#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1const int maxn=100005;int tree[maxn<<2],lz[maxn<<2];void pushdown(int rt){    lz[rt<<1]+=lz[rt];    lz[rt<<1|1]+=lz[rt];    lz[rt]=0;}void update(int L,int R,int val,int l,int r,int rt){    if(L<=l&&r<=R)    {        lz[rt]+=val;        return ;    }    pushdown(rt);    int mid=(l+r)>>1;    if(R<=mid)    {        update(L,R,val,lson);        return ;    }    if(L>mid)    {        update(L,R,val,rson);        return ;    }    update(L,R,val,lson);    update(L,R,val,rson);}int query(int pos,int l,int r,int rt){    if(l==r)    {        return tree[rt]+lz[rt];    }    int mid=(l+r)>>1;    pushdown(rt);    if(pos<=mid)        return query(pos,lson);    else        return query(pos,rson);}bool hash[maxn];int a[maxn];struct qyy{    int l,r,id;    qyy(){}    qyy(int a,int b,int c)    {        l=a;r=b;id=c;    }    bool operator< (const qyy& a) const    {        return r<a.r;    }}qy[maxn];struct optt{    int ans,id;    optt(){}    optt(int a,int b)    {        ans=a;id=b;    }    bool operator< (const optt& a) const    {        return id<a.id;    }}opt[maxn];int pos[maxn];int main(){    int t,n,m,i,j,l,r,cnt,tmp,tmp2,val,ccnt,ocnt;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        for(i=1;i<=n;++i)        {            scanf("%d",&a[i]);            pos[a[i]]=i;        }        cnt=0;        for(i=1;i<=m;++i)        {            scanf("%d%d",&l,&r);            qy[cnt].id=i;qy[cnt].l=l;qy[cnt].r=r;cnt++;        }        sort(qy,qy+cnt);        memset(hash,false,sizeof(hash));        memset(tree,0,sizeof(tree));memset(lz,0,sizeof(lz));        ccnt=0,ocnt=0;        for(r=1;r<=n;++r)        {            val=a[r];            if(!hash[val-1]&&!hash[val+1])            {                update(1,r,1,1,n,1);            }            else if(hash[val-1]&&!hash[val+1])            {                tmp=pos[val-1];                update(tmp+1,r,1,1,n,1);            }            else if(!hash[val-1]&&hash[val+1])            {                tmp=pos[val+1];                update(tmp+1,r,1,1,n,1);            }            else if(hash[val-1]&&hash[val+1])            {                tmp=min(pos[val-1],pos[val+1]);                tmp2=max(pos[val-1],pos[val+1]);                update(1,tmp,-1,1,n,1);                update(tmp2+1,r,1,1,n,1);            }            hash[val]=true;            while(ccnt<cnt&&qy[ccnt].r==r)            {                opt[ocnt].ans=query(qy[ccnt].l,1,n,1);                opt[ocnt].id=qy[ccnt].id;                ocnt++;ccnt++;            }            if(ccnt==cnt)                break;        }        sort(opt,opt+ocnt);        for(i=0;i<ocnt;++i)        {            printf("%d\n",opt[i].ans);        }    }    return 0;}


 

 

原创粉丝点击