zoukankan      html  css  js  c++  java
  • Uva 12436 Rip Van Winkle's Code

    Rip Van Winkle was fed up with everything except programming. One day he found a problem whichrequired to perform three types of update operations (A, B, C), and one query operation S over an arraydata[]. Initially all elements of data are equal to 0. Though Rip Van Winkle is going to sleep for 20years, and his code is also super slow, you need to perform the same update operations and output theresult for the query operation S in an efficient way.

    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;
    }

    Input

    The first line of input will contain T (≤ 4 ∗ 105) denoting the number of operations. Each of the nextT lines starts with a character (‘A’, ‘B’, ‘C’ or ‘S’), which indicates the type of operation. Character ‘A’,‘B’ or ‘S’ will be followed by two integers, st and nd in the same line. Character ‘C’ is followed by threeintegers, st, nd and x. It’s assumed that, 1 ≤ st ≤ nd ≤ 250000 and −105 ≤ x ≤ 105. The meaningsof these integers are explained by the code of Rip Van Winkle.

    Output

    For each line starting with the character ‘S’, print S(st, nd) as defined in the code.

    Sample Input

    7
    A 1 4
    B 2 3
    S 1 3
    C 3 4 -2
    S 2 4
    B 1 3
    S 2 4

    Sample Output

    9

    0

    3

    这题是区间更新,这题比较麻烦,做了很长时间。先用线段树维护l,r,add1(线段左端点加的值),add2(线段右端点加的值),step(区间的公差,右边减去左边的),sum(区间总和),flag(判断区间是否数字相同),value(区间数字都相同时的数值大小).我的思路是每一次更新,都把这一段的sum值直接表示出来,如果更新的这条线段小于当前线段,那么先不更新sum值,而是b[th].sum=b[lth].sum+b[rth].sum;


    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef long double ldb;
    #define lth th<<1
    #define rth th<<1|1
    #define inf 99999999
    #define pi acos(-1.0)
    #define MOD 100000007
    #define maxn 250050
    struct node{
        int l,r;
        ll value,flag;  //flag表示这段是不是值都是相同的,value是这段的值
        ll add1,step,add2; //add1表示左端点加的值,add2表示右端点,step表示这段的公差
        ll sum;
    }b[4*maxn];
    
    void build(int l,int r,int th)
    {
        int mid;
        b[th].l=l;b[th].r=r;
        b[th].value=0;b[th].flag=1;
        b[th].add1=b[th].step=b[th].add2=0;
        b[th].sum=0;
        if(l==r)return;
        mid=(l+r)/2;
        build(l,mid,lth);
        build(mid+1,r,rth);
    }
    void pushdown(int th)
    {
        int mid;
        mid=(b[th].l+b[th].r)/2;
        if(b[th].flag){
            b[th].flag=0;
            b[lth].flag=1;
            b[lth].value=b[th].value;
            b[lth].add1=b[lth].add2=b[lth].step=0;
            b[lth].sum=(b[lth].r-b[lth].l+1)*b[th].value;
    
            b[rth].flag=1;
            b[rth].value=b[th].value;
            b[rth].add1=b[rth].add2=b[rth].step=0;
            b[rth].sum=(b[rth].r-b[rth].l+1)*b[th].value;
        }
    
        ll add1,add2;
        add1=b[th].add1; add2=b[th].add1+(mid-b[th].l)*b[th].step;
        b[lth].add1+=add1;
        b[lth].add2+=add2;
        b[lth].step+=b[th].step;
        b[lth].sum+=(add1+add2)*(b[lth].r-b[lth].l+1)/2;
    
        ll add3,add4;
        add3=add2+b[th].step;add4=add3+(b[th].r-(mid+1))*b[th].step;
        b[rth].add1+=add3;
        b[rth].add2+=add4;
        b[rth].step+=b[th].step;
        b[rth].sum+=(add3+add4)*(b[rth].r-b[rth].l+1)/2;
    
        b[th].add1=b[th].add2=b[th].step=0;
    }
    void pushup(int th)
    {
        b[th].sum=b[lth].sum+b[rth].sum;
    }
    
    void update(int l,int r,ll add,int f,int th)
    {
        int mid;
        if(b[th].l==l && b[th].r==r){
            if(f==1){
                b[th].add1+=add;
                b[th].add2+=add+b[th].r-b[th].l;
                b[th].step+=1;
                b[th].sum+=(add+add+b[th].r-b[th].l)*(b[th].r-b[th].l+1)/2;
                return;
            }
            else if(f==2){
                b[th].add1+=add+b[th].r-b[th].l;
                b[th].add2+=add;
                b[th].step-=1;
                b[th].sum+=(add+add+b[th].r-b[th].l)*(b[th].r-b[th].l+1)/2;
                return;
            }
            else if(f==3){
                b[th].flag=1;
                b[th].value=add;
                b[th].sum=b[th].value*(b[th].r-b[th].l+1);
                b[th].add1=b[th].add2=b[th].step=0;
                return;
            }
        }
        pushdown(th);
        mid=(b[th].l+b[th].r)/2;
        if(r<=mid)update(l,r,add,f,lth);
        else if(l>mid)update(l,r,add,f,rth);
        else{
            if(f==1){
                update(l,mid,add,f,lth);
                update(mid+1,r,add+(mid+1-l),f,rth);
            }
            else if(f==2){
                update(l,mid,add+(r-mid),f,lth);
                update(mid+1,r,add,f,rth);
            }
            else if(f==3){
                update(l,mid,add,f,lth);
                update(mid+1,r,add,f,rth);
            }
        }
        pushup(th);
    }
    ll question(int l,int r,int th)
    {
        int mid;
        if(b[th].l==l && b[th].r==r){
            return b[th].sum;
        }
        pushdown(th);
        mid=(b[th].l+b[th].r)/2;
        if(r<=mid)return question(l,r,lth);
        else if(l>mid)return question(l,r,rth);
        else{
            return question(l,mid,lth)+question(mid+1,r,rth);
        }
    }
    int main()
    {
        int m,i,j,T,c,d;
        ll n,num;
        char s[10];
        while(scanf("%lld",&n)!=EOF)
        {
            build(1,250010,1);
            for(i=1;i<=n;i++){
                scanf("%s%d%d",s,&c,&d);
                if(s[0]=='A'){
                    update(c,d,1,1,1);
                }
                else if(s[0]=='B'){
                    update(c,d,1,2,1);
                }
                else if(s[0]=='C'){
                    scanf("%lld",&num);
                    update(c,d,num,3,1);
                }
                else if(s[0]=='S'){
                    printf("%lld
    ",question(c,d,1) );
                }
            }
        }
        return 0;
    }
    


  • 相关阅读:
    程序员下班去超市购物与收银员的一段搞笑对白 续集
    2010年9月02日周四_Deploying ArcGIS Mobile applications_4.1
    2010年8月30日周一_Adding layers _7.2
    2010年8月30日周一_Creating A Map_7.1
    2010年9月01日周三_CreatingAndPublishingaMobileWebService_3.2
    2010年8月29日周日_Deployment_6
    2010年8月31日周二_Navigating the map_7.3
    2010年8月30日周一_Introduction to ArcGIS Mobile SDK_1
    2010年9月01日周三_Using GPS data and devices_3.3
    2010年8月29日周日_Using the Sample Xcode Projects_5
  • 原文地址:https://www.cnblogs.com/herumw/p/9464707.html
Copyright © 2011-2022 走看看