hdu4973 A simple simulation problem. 线段树

来源:互联网 发布:爱宕 犬 数据 编辑:程序博客网 时间:2024/06/02 01:57
hdu4973 A simple simulation problem.
每种type的细胞为一个点建线段树,翻倍时找到相应区间翻倍即可。注意头尾特殊处理。

真的是很simple的线段树题目。
需要完成单点加,区间乘,询问区间最大值,询问区间和几个操作。

就是这么简单的题目被我写了将近4小时。
没什么好说的。

代码中的node是没有必要的,记录一个最大值即可,因为不需要知道位置(题目看搓了……)。

#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define ls (p<<1)#define rs (p<<1|1)#define Maxn 50100struct node{int pos;long long ma;};struct segtree{int l,r;long long tag,sum;node d;}t[Maxn*4];void lazy(int p){    if (t[p].l==t[p].r) return;    if (t[p].tag!=1){        t[ls].tag*=t[p].tag;        t[rs].tag*=t[p].tag;        t[ls].sum*=t[p].tag;        t[rs].sum*=t[p].tag;        t[ls].d.ma*=t[p].tag;t[rs].d.ma*=t[p].tag;        t[p].tag=1;    }    if (t[ls].d.ma>t[rs].d.ma) t[p].d=t[ls].d;    else t[p].d=t[rs].d;}void update(int p){    if (t[p].l==t[p].r) return;    if (t[ls].d.ma>t[rs].d.ma) t[p].d=t[ls].d;    else t[p].d=t[rs].d;    t[p].sum=t[ls].sum+t[rs].sum;}void build(int l,int r,int p){    t[p].l=l;t[p].r=r;t[p].tag=1;    if (l==r){        t[p].d.pos=l;        t[p].d.ma=1;        t[p].sum=1;        return;    }    int m=l+r>>1;    build(l,m,ls);    build(m+1,r,rs);    update(p);}void add(int pos,int p,long long val){    if (t[p].l==t[p].r){t[p].sum+=val;t[p].d.ma+=val;return;}    lazy(p);    int m=t[p].l+t[p].r>>1;    if (pos<=m) add(pos,ls,val);    else add(pos,rs,val);    update(p);}void mul(int l,int r,int p){    if (t[p].l==l&&t[p].r==r){        t[p].sum*=2;        t[p].d.ma*=2;        t[p].tag*=2;        return;    }    lazy(p);    int m=t[p].l+t[p].r>>1;    if (r<=m) mul(l,r,ls);    else if (l>m) mul(l,r,rs);    else {        mul(l,m,ls);        mul(m+1,r,rs);    }    update(p);}node query1(int l,int r,int p){    if (t[p].l==l&&r==t[p].r){        return t[p].d;    }    lazy(p);    int m=t[p].l+t[p].r>>1;    node ret;    if (r<=m) ret=query1(l,r,ls);    else if (l>m) ret=query1(l,r,rs);    else{        node n1=query1(l,m,ls);        node n2=query1(m+1,r,rs);        if (n1.ma>n2.ma){            ret=n1;        }        else ret=n2;    }    update(p);    return ret;}long long query2(int l,int r,int p){    if (t[p].l==l&&t[p].r==r){        return t[p].sum;    }    lazy(p);    int m=t[p].l+t[p].r>>1;    long long ret;    if (r<=m) ret=query2(l,r,ls);    else if (l>m) ret=query2(l,r,rs);    else{        ret=query2(l,m,ls)+query2(m+1,r,rs);    }    update(p);    return ret;}int n;int getpos(long long num,int p){    if (t[p].l==t[p].r) return t[p].l;    lazy(p);    int ret;    if (num>t[ls].sum) {        ret=getpos(num-t[ls].sum,rs);    }    else{        ret=getpos(num,ls);    }    update(p);    return ret;}long long max(long long a,long long b){return a>b?a:b;}int main(){    //freopen("1003in.txt","r",stdin);    int tcas,cas,m,i,l,r;    long long a,b,ta,tb,ans;    node nd;    char s[10];    scanf("%d",&tcas);    for(cas=1;cas<=tcas;++cas){        scanf("%d%d",&n,&m);        build(1,n,1);        printf("Case #%d:\n",cas);        for(i=1;i<=m;++i){            scanf("%s%I64d%I64d",s,&a,&b);            if (s[0]=='D'){                l=getpos(a,1);                r=getpos(b,1);                if (l==r){                    add(l,1,b+1-a);                }                else{                    ta=query2(1,l,1);                    ta=ta+1-a;                    long long tc=tb=query2(1,r-1,1);                    tb=b-tb;                    add(l,1,ta);                    add(r,1,tb);                    l+=1;r-=1;                    if (l<=r) mul(l,r,1);                }            }            else{                l=getpos(a,1);                r=getpos(b,1);                if (l==r) {                    printf("%I64d\n",b+1-a);                }                else{                    ta=query2(1,l,1);                    ta=ta+1-a;                    tb=query2(1,r-1,1);                    tb=b-tb;                    l+=1;                    r-=1;                    if (l<=r) {nd=query1(l,r,1);}                    else nd.ma=0;                    ans=max(ta,max(tb,nd.ma));                    printf("%I64d\n",ans);                }            }        }    }    return 0;}



0 0
原创粉丝点击