zoukankan      html  css  js  c++  java
  • spoj gss2 : Can you answer these queries II 离线&&线段树

    1557. Can you answer these queries II

    Problem code: GSS2


     

    Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in contests.

    When having a contest, Yang Zhe looks at the score of every problems first. For the problems of the same score, Yang Zhe will do only one of them. If he's lucky enough, he can get all the scores wanted.

    Amber is going to hold a contest in SPOJ. She has made a list of N candidate problems, which fit Yang Zhe very well. So Yang Zhe can solve any problem he want. Amber lined up the problems, began to select. She will select a subsequence of the list as the final problems. Being A girl of great compassion, she'd like to select such a subsequence (can be empty) that Yang Zhe will get the maximal score over all the possible subsequences.

    Amber found the subsequence easily after a few minutes. To make things harder, Amber decided that, Yang Zhe can take this contest only if Yang Zhe can answer her Q questions. The question is: if the final problems are limited to be a subsequence of list[X..Y] (1 <= X <= Y <= N), what's the maximal possible score Yang Zhe can get?

    As we know, Yang Zhe is a bit idiot (so why did he solve the problem with a negative score?), he got Wrong Answer again... Tell him the correct answer!

    Input

    • Line 1: integer N (1 <= N <= 100000);
    • Line 2: N integers denoting the score of each problem, each of them is a integer in range [-100000, 100000];
    • Line 3: integer Q (1 <= Q <= 100000);
    • Line 3+i (1 <= i <= Q): two integers X and Y denoting the ith question.

    Output

    • Line i: a single integer, the answer to the ith question.

    Example

    Input:
    9
    4 -2 -2 3 -1 -4 2 2 -6
    3
    1 2
    1 5
    4 9
    
    Output:
    4
    5
    3
    
    

      见过变态的线段树,没见过这么变态的。。。。。。
      在我看来,这个线段树lazy标记的传递奇葩之处在于用到了lazy标记传递的一个隐藏的规律:即某个标记被改变意味着它上方不存在其他标记,因此一个标记下放时,其下方标记作用的时间域和此标记是没有交集的。
      我做这道题参考的题解:http://blog.csdn.net/acm_cxlove/article/details/7854526  (注意一下:那个题解的标程没开long long)
      两个lazy标记:lazy:标记代表的那一段时间区间增加的量 lazy2:对应时间区间增加量的最值
      维护两个值:mx:这个区间当前最大值 his:这个区间历史最大值
      其他参见连接题解。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXQ 110000
    #define MAXR 200200
    #define VAL1 100100
    #define MAXN 101000
    #define MAXT 410000
    #define lch (now<<1)
    #define rch (now<<1^1)
    #define INFL 0x3f3f3f3f3f3f3f3fLL
    #ifdef WIN32
    #define LL "%I64d"
    #else 
    #define LL "%lld"
    #endif
    typedef long long qword;
    int n,m;
    struct node
    {
            int l,r;
            qword mx;
            qword his;
            qword lazy;//delta
            qword lazy2;//delta_max
    }tree[MAXT];
    void down(int now)
    {
            if (tree[now].l==tree[now].r)
            {
                    tree[now].lazy=0;
                    tree[now].lazy2=0;
                    return ;
            }
            tree[lch].lazy2=max(tree[lch].lazy2,tree[lch].lazy+tree[now].lazy2);
            tree[rch].lazy2=max(tree[rch].lazy2,tree[rch].lazy+tree[now].lazy2);
            tree[lch].his=max(tree[lch].his,tree[lch].mx+tree[now].lazy2);
            tree[rch].his=max(tree[rch].his,tree[rch].mx+tree[now].lazy2);
            tree[lch].mx+=tree[now].lazy;
            tree[rch].mx+=tree[now].lazy;
            tree[lch].lazy+=tree[now].lazy;
            tree[rch].lazy+=tree[now].lazy;
            tree[now].lazy=0;
            tree[now].lazy2=0;
    }
    void up(int now)
    {
            if (tree[now].l==tree[now].r)return ;
            tree[now].mx=max(tree[lch].mx,tree[rch].mx);
            tree[now].his=max(tree[lch].his,tree[rch].his);
    }
    void build_tree(int now,int l,int r)
    {
            tree[now].l=l;
            tree[now].r=r;
            tree[now].his=0;
            tree[now].lazy=0;
            tree[now].lazy2=0;
            tree[now].mx=0;
            if (l==r)
            {
                    return ;
            }
            int mid=(l+r)/2;
            build_tree(lch,l,mid);
            build_tree(rch,mid+1,r);
    }
    void add_val(int now,int l,int r,qword z)
    {
            if (l==tree[now].l&&r==tree[now].r)
            {
                    tree[now].lazy+=z;
                    tree[now].lazy2=max(tree[now].lazy2,tree[now].lazy);
                    tree[now].mx+=z;
                    tree[now].his=max(tree[now].mx,tree[now].his);
                    return ;
            }
            down(now);
            int mid=(tree[now].l+tree[now].r)/2;
            if (r<=mid)
            {
                    add_val(lch,l,r,z);
                    up(now);
                    return ;
            }
            if (mid<l)
            {
                    add_val(rch,l,r,z);
                    up(now);
                    return ;
            }
            add_val(lch,l,mid,z);
            add_val(rch,mid+1,r,z);
            up(now);
    }
    qword get_max(int now,int l,int r)
    {
            if (l==tree[now].l&&r==tree[now].r)
            {
                    return tree[now].his;
            }
            int mid=(tree[now].l+tree[now].r)/2;
            down(now);
            if (r<=mid)
            {
                    return get_max(lch,l,r);
            }
            if (mid<l)
            {
                    return get_max(rch,l,r);
            }
            qword t;
            t= max(get_max(lch,l,mid),get_max(rch,mid+1,r));
            up(now);
            return t;
    }
    int num[MAXN];
    int rec[MAXR];
    int prev[MAXN];
    struct qur_t
    {
            int x,y,id;
            qword ans;
    }qur[MAXQ];
    bool cmp_y(const qur_t &q1,const qur_t &q2)
    {
            return  q1.y<q2.y;
    }
    bool cmp_id(const qur_t &q1,const qur_t &q2)
    {
            return q1.id<q2.id;
    }
    int main()
    {
            freopen("input.txt","r",stdin);
            int i,j,k,x,y,z;
            scanf("%d",&n);
            memset(rec,-1,sizeof(rec));
            for (i=0;i<n;i++)
            {
                    scanf("%d",&num[i]);
                    prev[i]=rec[num[i]+VAL1];
                    rec[num[i]+VAL1]=i;
            }
            scanf("%d",&m);
            for (i=0;i<m;i++)
            {
                    scanf("%d%d",&qur[i].x,&qur[i].y);
                    qur[i].x--;
                    qur[i].y--;
                    qur[i].id=i;
            }
            sort(qur,&qur[m],cmp_y);
            int now=-1;
            build_tree(1,0,n-1);
            for (i=0;i<m;i++)
            {
                    while (now<qur[i].y)
                    {
                            now++;
            //                cout<<"Add:"<<prev[now]+1<<"~"<<now<<":"<<num[now]<<endl;
                            add_val(1,prev[now]+1,now,num[now]);
                    }
            //        cout<<"Query:"<<qur[i].x<<"~"<<qur[i].y<<endl;
                    qur[i].ans=get_max(1,qur[i].x,qur[i].y);
            }
            sort(qur,&qur[m],cmp_id);
            //    cout<<"a"<<endl;
            for(i=0;i<m;i++)
            {
                    printf(LL "
    ",qur[i].ans);
            }
    }
     
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    Vue-dialog(弹框组件)
    Vue封装select下拉组件
    RAID总结
    消息队列
    存储
    算法开始
    硬件杂记
    要看的
    关于kernel的疑问,不解
    杂技
  • 原文地址:https://www.cnblogs.com/mhy12345/p/3869229.html
Copyright © 2011-2022 走看看