XTU 1205 Range

还是五月湘潭赛的题目,当时就是因为我坑。。。连个银牌都没拿到,擦。

这个题目枚举区间是不可能的,明显是要考虑每个数对全局的影响,即找到每个数最左和最右能满足是最大的位置 以及 最小的时候,相乘即为该数字影响的区间总数。当时想到的是用线段树,建树的时候求出最大和最小值,然后在每个数往里面搜索,比赛的时候敲挫了,那个时候真的线段树写的很挫,而且没考虑过一个问题,就是相同的时候怎么办,按刚刚的算法,会算重复的,所以一个好的方法是如果有相同的,往左搜的时候搜到等于该数值的时候停止,往右搜的时候搜到大于该数值的时候停止(求最大的时候),求最小的时候也是一样的处理

然后搜左边的时候优先走右子树,右子树没有 再找左子树。。同理右边先搜左孩子,没有再搜右孩子,注意些细节以及可以剪剪枝。

线段树写这个题目其实很费力,有种更好的方法用桟来做,栈在求最大最小的时候往往很给力,像这个题目,我比如在求左边最大的时候,我当前数,如果碰到栈顶数比它大于等于的,就直接停止了,入桟,否则就一直pop下去,直到遇到比它大于等于的或者桟空,这个时候得到了左边区间最大,并且把当前值放进去,因为我只保留左边区间离下个数最近的最大的数即可,如果连这个数都不能阻挡下一个数,那之前被pop掉的肯定也阻挡不了,所以扫一遍即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define LL __int64
using namespace std;
const int N = 100010;
int dmin[N<<2],dmax[N<<2];
int A[N];
int n;
void build(int rt,int l,int r)
{
    if (l>=r){
        dmin[rt]=A[l];
        dmax[rt]=A[l];
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    dmax[rt]=max(dmax[rt<<1],dmax[rt<<1|1]);
    dmin[rt]=min(dmin[rt<<1],dmin[rt<<1|1]);
}
int query1(int L,int R,int val,int rt,int l,int r)
{
    if (L>R) return R;
    if (l>=r){
        if(l>=L &&l<=R && A[l]>=val){
            return l;
        }
        else return 0;
    }
    int mid=(l+r)>>1;
    if (R<=mid){
        if (dmax[rt<<1]>=val)
        return query1(L,R,val,lson);
        else return 0;
    }
    int ret=0;
    if (dmax[rt<<1|1]>=val){
        ret=query1(L,R,val,rson);
    }
    if (ret>0) return ret;
    if (dmax[rt<<1]>=val)
    return query1(L,R,val,lson);
    else return 0;
}
int query2(int L,int R,int val,int rt,int l,int r)
{
    if (L>R) return L;
    if (l>=r){
        if (l>=L && l<=R && A[l]>=val){
            return l;
        }
        else return n+1;
    }
    int mid=(l+r)>>1;
    if (L>mid){
        if (dmax[rt<<1|1]>=val)
        return query2(L,R,val,rson);
        else return n+1;
    }
    int ret=n+1;
    if (dmax[rt<<1]>=val){
        ret=query2(L,R,val,lson);
    }
    if (ret<n+1) return ret;
    if (dmax[rt<<1|1]>=val)
    return query2(L,R,val,rson);
    else return n+1;
}
int query3(int L,int R,int val,int rt,int l,int r)
{
    if (L>R) return R;
    if (l>=r){
        if (L<=l && l<=R && A[l]<=val){
            return l;
        }
        else return 0;
    }
    int mid=(l+r)>>1;

    if (R<=mid){
        if (dmin[rt<<1]<=val){
            return query3(L,R,val,lson);
        }
        else return 0;
    }
    int ret=0;
    if (dmin[rt<<1|1]<=val) ret=query3(L,R,val,rson);
    if (ret>0) return ret;
    if (dmin[rt<<1]<=val)
    return query3(L,R,val,lson);
    else return 0;
}
int query4(int L,int R,int val,int rt,int l,int r)
{
    if (L>R) return L;
    if (l>=r){
        if (L<=l && r<=R && A[l]<=val){
            return l;
        }
        else return n+1;
    }
    int mid=(l+r)>>1;
    if (L>mid){
        if (dmin[rt<<1|1]<=val){
            return query4(L,R,val,rson);
        }
        else return n+1;
    }
    int ret=n+1;
    if (dmin[rt<<1]<=val){
        ret=query4(L,R,val,lson);
    }
    if (ret<n+1) return ret;
    else
    if (dmin[rt<<1|1]<=val) return query4(L,R,val,rson);
    return n+1;
}
int main()
{
    int t;
    int kase=0;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&A[i]);
        build(1,1,n);
        LL sum=0;
        for (int i=1;i<=n;i++){
            int l1=query1(1,i-1,A[i],1,1,n);
            int l2=query2(i+1,n,A[i]+1,1,1,n);
            int l3=query3(1,i-1,A[i],1,1,n);
            int l4=query4(i+1,n,A[i]-1,1,1,n);
            //cout<<"Test "<<i<<endl;
           // cout<<l1<<" "<<l2<<" "<<l3<<" "<<l4<<endl;
            sum+=(LL)(i-l1)*(LL)(l2-i)*(LL)A[i];
            sum-=(LL)(i-l3)*(LL)(l4-i)*(LL)A[i];
        }
        sum+=(LL)n*(n+1)/2;
        printf("Case %d: %I64d\n",++kase,sum);
    }
    return 0;
}
时间: 2024-08-10 02:10:18

XTU 1205 Range的相关文章

2014湘潭邀请赛 C题 湘大OJ 1205 Range (单调栈)

Problem Description For an array, the range function is defined below: Range(A)=Max(A)-Min(A)+1; For example, suppose A={1,2,3,4,5}, then Range(A)=5-1+1=5. Now, given an array A(length≤100000), you are going to calcalute the sum of all subarray's ran

XTUOJ 1205 Range

Range Time Limit : 1000 MS Memory Limit : 65536 KB Problem Description For an array, the range function is defined below: Range(A)=Max(A)-Min(A)+1; For example, suppose A={1,2,3,4,5}, then Range(A)=5-1+1=5. Now, given an array A(length≤100000), you a

xtu summer individual 5 D - Subsequence

Subsequence Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 353064-bit integer IO format: %I64d      Java class name: Main There is a sequence of integers. Your task is to find the longest subsequence that sa

xtu read problem training 4 B - Multiplication Puzzle

Multiplication Puzzle Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 165164-bit integer IO format: %lld      Java class name: Main The multiplication puzzle is played with a row of cards, each containing a s

xtu字符串 C. Marlon&#39;s String

C. Marlon's String Time Limit: 2000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Long long ago, there was a coder named Marlon. One day he picked two string on the street. A problem suddenly crash his brain... Let

xtu summer individual 1 D - Round Numbers

D - Round Numbers Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'R

xtu数据结构 G. Count the Colors

G. Count the Colors Time Limit: 2000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is

range()用法

来源:http://www.cnblogs.com/wangwp/p/4535299.html 例子:http://www.cnblogs.com/hongten/p/hongten_python_range.html 函数原型:range(start, end, scan): 参数含义:start:计数从start开始.默认是从0开始.例如range(5)等价于range(0, 5); end:技术到end结束,但不包括end.例如:range(0, 5) 是[0, 1, 2, 3, 4]没有

Leetcode 34. Search for a Range

34. Search for a Range Total Accepted: 91570 Total Submissions: 308037 Difficulty: Medium Given a sorted array of integers, find the starting and ending position of a given target value. Your algorithm's runtime complexity must be in the order of O(l