码迷,mamicode.com
首页 > Windows程序 > 详细

UVA 12436-Rip Van Winkle's Code(线段树的区间更新)

时间:2015-08-10 21:52:24      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:

题意:

long long data[250001];

void A( int st, int nd ) { for( int i = st; i \le nd; i++ ) data[i] = data[i] + (i - st + 1); }

void B( int st, int nd ) { for( int i = st; i \le nd; i++ ) data[i] = data[i] + (nd - i + 1); }

void C( int st, int nd, int x ) { for( int i = st; i \le nd; i++ ) data[i] = x; }

long long S( int st, int nd ) { long long res = 0; for( int i = st; i \le nd; i++ ) res += data[i]; return res; }

四个函数,对应四种操作A、B、C、S给出m个操作,求s操作时返回的结果。

分析:

明显的线段树的区间更新,但懒惰标记的选择要想一想,C这个操作好处理、我们观察A、B发现都是加上一个等差数列、等差数列加等差数列还是等差数列、那我们选择等差数列的首项和公差做标记。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<1|1
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
#define N 250001
const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod =  1000000007;
struct node{
    ll a1,d,sum,setv;
    int l,r;
}t[N<<2];
void pushup(int rt){
    t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
}
void pushdown(int rt){
    if(t[rt].setv!=INF){
        t[rt<<1].setv=t[rt<<1|1].setv=t[rt].setv;
        t[rt<<1].a1=t[rt<<1].d=t[rt<<1|1].a1=t[rt<<1|1].d=0;
        t[rt<<1].sum=1LL*(t[rt<<1].r-t[rt<<1].l+1)*t[rt].setv;
        t[rt<<1|1].sum=1LL*(t[rt<<1|1].r-t[rt<<1|1].l+1)*t[rt].setv;
        t[rt].setv=INF;
    }
    if(t[rt].a1||t[rt].d){
        ll len1=t[rt<<1].r-t[rt<<1].l+1;
        ll len2=t[rt<<1|1].r-t[rt<<1|1].l+1;
        ll tmp1=t[rt].a1;
        ll tmp2=tmp1+len1*t[rt].d;
        t[rt<<1].a1+=tmp1;
        t[rt<<1|1].a1+=tmp2;
        t[rt<<1].d+=t[rt].d;
        t[rt<<1|1].d+=t[rt].d;
        t[rt<<1].sum+=tmp1*len1+len1*(len1-1)/2*t[rt].d;//等差数列求和
        t[rt<<1|1].sum+=tmp2*len2+len2*(len2-1)/2*t[rt].d;
        t[rt].a1=t[rt].d=0;
    }
}
void build(int l,int r,int rt){
    t[rt].l=l;
    t[rt].r=r;
    t[rt].sum=t[rt].a1=t[rt].d=0;
    t[rt].setv=INF;
    if(l==r)return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
   pushup(rt);
}
void update_add(int l,int r,int rt,ll d){
    if(l<=t[rt].l&&r>=t[rt].r){
        ll a1=(d==1)?(t[rt].l-l+1):(r-t[rt].l+1);//确定首项
        ll len=t[rt].r-t[rt].l+1;
         t[rt].a1+=a1;
         t[rt].d+=d;
         t[rt].sum+=a1*len+len*(len-1)/2*d;
         return;
    }
    pushdown(rt);
    int m=(t[rt].l+t[rt].r)>>1;
    if(l<=m)update_add(l,r,rt<<1,d);
    if(r>m)update_add(l,r,rt<<1|1,d);
    pushup(rt);
}
void update_set(int l,int r,int rt,ll x){
    if(l<=t[rt].l&&r>=t[rt].r){
        t[rt].setv=x;
        t[rt].a1=t[rt].d=0;
        t[rt].sum=1LL*(t[rt].r-t[rt].l+1)*x;
        return;
    }
    pushdown(rt);
    int m=(t[rt].l+t[rt].r)>>1;
    if(l<=m)update_set(l,r,rt<<1,x);
    if(r>m)update_set(l,r,rt<<1|1,x);
    pushup(rt);
}
ll query(int l,int r,int rt){
    if(l<=t[rt].l&&r>=t[rt].r){
        return t[rt].sum;
    }
    pushdown(rt);
    ll num=0;
    int m=(t[rt].l+t[rt].r)>>1;
    if(l<=m)num+=query(l,r,rt<<1);
    if(r>m)num+=query(l,r,rt<<1|1);
    return num;
}
int main()
{
    int n,tll,trr;
    ll x;
    char op[3];
     build(1,N,1);
    scanf("%d",&n);
        while(n--){
            scanf("%s%d%d",op,&tll,&trr);
            if(op[0]==A){
                update_add(tll,trr,1,1);
            }
            else if(op[0]==B)
                update_add(tll,trr,1,-1);
            else if(op[0]==C){
                scanf("%lld",&x);
                update_set(tll,trr,1,x);
            }
            else if(op[0]==S){
                printf("%lld\n",query(tll,trr,1));
            }
        }
return 0;
}

 

UVA 12436-Rip Van Winkle's Code(线段树的区间更新)

标签:

原文地址:http://www.cnblogs.com/zsf123/p/4719100.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!