HDU 4348 SPOJ TTM To the moon(操作建树)

来源:互联网 发布:linux查看服务列表 编辑:程序博客网 时间:2024/05/21 11:08

题意:给出一个序列,四种操作

C l r d: Adding a constant d for every {Ai | l <= i <= r}, and increase the timestamp by 1, this is the only operation that will cause the timestamp increase. Q l r: Querying the current sum of {Ai | l <= i <= r}.H l r t: Querying a history sum of {Ai | l <= i <= r} in time t.B t: Back to time t. And once you decide return to a past, you can never be access to a forward edition anymore.

对于操作建树,只有当遇到C时时间戳才上升,时间对应的结点建树,dfs整棵树线段树更新区间得到答案

#include<cstring>#include<string>#include<iostream>#include<queue>#include<cstdio>#include<algorithm>#include<map>#include<cstdlib>#include<cmath>#include<vector>//#pragma comment(linker, "/STACK:1024000000,1024000000");using namespace std;#define INF 0x3f3f3f3f#define maxn 200005int n,m;int fir[maxn],nex[maxn],v[maxn],e_max;long long sum[4*maxn],tag[4*maxn],ans[maxn];struct Q{    char s[3];    int l,r,c,id;    friend bool operator < (Q A,Q B)    {        return A.id<B.id;    }} q[maxn];void init_(){    memset(fir,-1,sizeof fir);    e_max=0;}void add_edge(int s,int t){    int e=e_max++;    v[e]=t;    nex[e]=fir[s];    fir[s]=e;}void init(int l,int r,int k){    tag[k]=sum[k]=0;    if(l==r)    {        scanf("%lld",&sum[k]);        return ;    }    int mid=l+r>>1;    init(l,mid,k<<1);    init(mid+1,r,k<<1|1);    sum[k]=sum[k<<1]+sum[k<<1|1];}void pushdown(int k,int l,int r){    if(!tag[k]) return ;    int mid=l+r>>1;    tag[k<<1]+=tag[k];    sum[k<<1]+=tag[k]*(mid-l+1);    tag[k<<1|1]+=tag[k];    sum[k<<1|1]+=tag[k]*(r-mid);    tag[k]=0;}void update(int d,int s,int t,int l,int r,int k){    if(s==l&&r==t)    {        sum[k]+=(r-l+1)*(long long)d;        tag[k]+=d;        return ;    }    pushdown(k,l,r);    int mid=l+r>>1;    if(t<=mid) update(d,s,t,l,mid,k<<1);    else if(s>mid) update(d,s,t,mid+1,r,k<<1|1);    else    {        update(d,s,mid,l,mid,k<<1);        update(d,mid+1,t,mid+1,r,k<<1|1);    }    sum[k]=sum[k<<1]+sum[k<<1|1];}long long query(int s,int t,int l,int r,int k){    if(s==l&&r==t)    {        return sum[k];    }    pushdown(k,l,r);    int mid=l+r>>1;    if(t<=mid) return query(s,t,l,mid,k<<1);    else if(s>mid) return query(s,t,mid+1,r,k<<1|1);    else return query(s,mid,l,mid,k<<1)+query(mid+1,t,mid+1,r,k<<1|1);}void dfs(int k){    for(int i=fir[k]; ~i; i=nex[i])    {        int e=v[i];        if(q[e].s[0]=='Q')        {            ans[q[e].id]=query(q[e].l,q[e].r,1,n,1);        }        else if(q[e].s[0]=='C')        {            update(q[e].c,q[e].l,q[e].r,1,n,1);            dfs(e);            update(-q[e].c,q[e].l,q[e].r,1,n,1);        }        else if(q[e].s[0]=='H')        {            ans[q[e].id]=query(q[e].l,q[e].r,1,n,1);        }    }}int ti[maxn];int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        init_();        init(1,n,1);        int now=0;        ti[now]=0;        for(int i=1; i<=m; i++)        {            scanf("%s",&q[i].s);            if(q[i].s[0]=='Q')            {                scanf("%d%d",&q[i].l,&q[i].r);                add_edge(ti[now],i);            }            else if(q[i].s[0]=='C')            {                scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].c);                add_edge(ti[now],i);                ti[++now]=i;            }            else if(q[i].s[0]=='H')            {                scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].c);                add_edge(ti[q[i].c],i);            }            else            {                scanf("%d",&q[i].c);                now=q[i].c;            }            q[i].id=i;        }        dfs(0);        for(int i=1; i<=m; i++)        {            if(q[i].s[0]=='H'||q[i].s[0]=='Q')                printf("%lld\n",ans[i]);        }    }    return 0;}
0 0
原创粉丝点击