HDU 3308 线段树

来源:互联网 发布:浏览器 网络连接错误 编辑:程序博客网 时间:2024/06/16 01:34

巨坑,手误超时

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <cmath>using namespace std;const int maxn = 1e5+10;struct node{    int l,r;    int le,ri,mi;//mi放最大值    int lazy;//是否要更新   int c;//区间长度}d[maxn<<2];int a[maxn];void build(int i,int l,int r){    d[i].l=l,d[i].r=r,d[i].le=d[i].ri=d[i].mi=1,d[i].c=r-l+1;    if(l==r) {d[i].le=d[i].ri=d[i].mi=1;return ;}    int mid=(d[i].r+d[i].l)>>1;    build(i<<1,l,mid);    build(i<<1|1,mid+1,r);    d[i].le=d[i<<1].le;    d[i].ri=d[i<<1|1].ri;    d[i].mi=max(d[i<<1].mi,d[i<<1|1].mi);    if(a[d[i<<1].r]<a[d[i<<1|1].l])    {        d[i].mi=max(d[i<<1].ri+d[i<<1|1].le,d[i].mi);        if(d[i<<1|1].ri==d[i<<1|1].c)            d[i].ri=d[i<<1|1].ri+d[i<<1].ri;        if(d[i<<1].le==d[i<<1].c)            d[i].le=d[i<<1].le+d[i<<1|1].le;    }}void sert(int i,int a1,int b1){    if(d[i].l==d[i].r)    {        return;    }    int mid=(d[i].r+d[i].l)>>1;    if(a1<=mid) sert(i<<1,a1,b1);    else sert(i<<1|1,a1,b1);   d[i].le=d[i<<1].le;    d[i].ri=d[i<<1|1].ri;    d[i].mi=max(d[i<<1].mi,d[i<<1|1].mi);    if(a[d[i<<1].r]<a[d[i<<1|1].l])    {        d[i].mi=max(d[i<<1].ri+d[i<<1|1].le,d[i].mi);        if(d[i<<1|1].ri==d[i<<1|1].c)            d[i].ri=d[i<<1|1].ri+d[i<<1].ri;        if(d[i<<1].le==d[i<<1].c)            d[i].le=d[i<<1].le+d[i<<1|1].le;    }}int query(int i,int a1,int b1){    if(d[i].l==a1&&d[i].r==b1)//这个手误,然后敲成了if(d[i].l==a1&&d[i].==b1)了,然后 每次就只能在叶子结点停了,,就会超时啊啊啊    {        return d[i].mi;    }    int mid=(d[i].r+d[i].l)>>1;    if(b1<=mid) return query(i<<1,a1,b1);    else if(a1>=mid+1) return query(i<<1|1,a1,b1);    else {        int x=query(i<<1,a1,mid);        int y=query(i<<1|1,mid+1,b1);        int ans2=0;        if(a[mid]<a[mid+1])        {           ans2+=min(d[i<<1|1].le,b1-mid);           ans2+=min(d[i<<1].ri,mid-a1+1);        }        return max(max(x,y),ans2);    }}int main(){    int T;    scanf("%d",&T);    while(T--)    {       // memset(d,0,sizeof(d));        int n,m;        scanf("%d %d",&n,&m);        for(int i=0;i<n;i++)            scanf("%d",&a[i]);        build(1,0,n-1);        char s[5];        int a1,b1;        for(int i=0;i<m;i++)        {            scanf("%s %d %d",s,&a1,&b1);            if(s[0]=='U'){                a[a1]=b1;                sert(1,a1,b1);            }            else            {                printf("%d\n",query(1,a1,b1));            }        }    }    return 0;}
原创粉丝点击