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

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

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

线段树写这个题目其实很费力,有种更好的方法用桟来做,栈在求最大最小的时候往往很给力,像这个题目,我比如在求左边最大的时候,我当前数,如果碰到栈顶数比它大于等于的,就直接停止了,入桟,否则就一直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 = ;
int dmin[N<<],dmax[N<<];
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)>>;
build(lson);
build(rson);
dmax[rt]=max(dmax[rt<<],dmax[rt<<|]);
dmin[rt]=min(dmin[rt<<],dmin[rt<<|]);
}
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 ;
}
int mid=(l+r)>>;
if (R<=mid){
if (dmax[rt<<]>=val)
return query1(L,R,val,lson);
else return ;
}
int ret=;
if (dmax[rt<<|]>=val){
ret=query1(L,R,val,rson);
}
if (ret>) return ret;
if (dmax[rt<<]>=val)
return query1(L,R,val,lson);
else return ;
}
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+;
}
int mid=(l+r)>>;
if (L>mid){
if (dmax[rt<<|]>=val)
return query2(L,R,val,rson);
else return n+;
}
int ret=n+;
if (dmax[rt<<]>=val){
ret=query2(L,R,val,lson);
}
if (ret<n+) return ret;
if (dmax[rt<<|]>=val)
return query2(L,R,val,rson);
else return n+;
}
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 ;
}
int mid=(l+r)>>; if (R<=mid){
if (dmin[rt<<]<=val){
return query3(L,R,val,lson);
}
else return ;
}
int ret=;
if (dmin[rt<<|]<=val) ret=query3(L,R,val,rson);
if (ret>) return ret;
if (dmin[rt<<]<=val)
return query3(L,R,val,lson);
else return ;
}
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+;
}
int mid=(l+r)>>;
if (L>mid){
if (dmin[rt<<|]<=val){
return query4(L,R,val,rson);
}
else return n+;
}
int ret=n+;
if (dmin[rt<<]<=val){
ret=query4(L,R,val,lson);
}
if (ret<n+) return ret;
else
if (dmin[rt<<|]<=val) return query4(L,R,val,rson);
return n+;
}
int main()
{
int t;
int kase=;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&A[i]);
build(,,n);
LL sum=;
for (int i=;i<=n;i++){
int l1=query1(,i-,A[i],,,n);
int l2=query2(i+,n,A[i]+,,,n);
int l3=query3(,i-,A[i],,,n);
int l4=query4(i+,n,A[i]-,,,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+)/;
printf("Case %d: %I64d\n",++kase,sum);
}
return ;
}

XTU 1205 Range的更多相关文章

  1. XTUOJ 1205 Range

    Range Time Limit : 1000 MS Memory Limit : 65536 KB Problem Description For an array, the range funct ...

  2. SQL Server 合并复制遇到identity range check报错的解决

        最近帮一个客户搭建跨洋的合并复制,由于数据库非常大,跨洋网络条件不稳定,因此只能通过备份初始化,在初始化完成后向海外订阅端插入数据时发现报出如下错误: Msg 548, Level 16, S ...

  3. Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range

    在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...

  4. [LeetCode] Range Addition 范围相加

    Assume you have an array of length n initialized with all 0's and are given k update operations. Eac ...

  5. [LeetCode] Count of Range Sum 区间和计数

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  6. [LeetCode] Range Sum Query 2D - Mutable 二维区域和检索 - 可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  7. [LeetCode] Range Sum Query - Mutable 区域和检索 - 可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  8. [LeetCode] Range Sum Query 2D - Immutable 二维区域和检索 - 不可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  9. [LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

随机推荐

  1. Springboot 项目启动设置

    //配置默认访问路径 并且自动打开浏览器  需要创建独立文件 @Controller public class HomeController {     @RequestMapping("/ ...

  2. 随机序列[SHOI2016](找规律+线段树)

    传送门 这道题的题意就是给你n个数让你在每个数之间插入+.-.*三种运算符中的一种,然后算出一个答案,再把答案加起来. 这题肯定是不能暴力的(题目都告诉你了由3n-1种结果).我们先从小的情况枚举找一 ...

  3. Java异常的限制

    Java异常的限制 我在看JAVA编程思想,讲到异常的限制,看的代码和解释,非常的难看下去,直接写了他的代码. java编程思想关于异常限制的逻辑 它以棒球比赛为例子. 定义了Inning(一局比赛) ...

  4. spinner的使用

    item.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...

  5. 「USACO08JAN」电话线Telephone Lines

    传送门 Luogu 解题思路 考虑二分,每次把大于二分值的边的权设为1,小于等于的设为0,如果最短路<=k则可行,记得判无解 细节注意事项 咕咕咕 参考代码 #include <algor ...

  6. 097、Java中String类之修改字符串对象引用

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  7. 题解 nflsoj550 【六校联合训练 省选 #9】序列

    题目链接 以下把值域(题面里的\(lim\))记做\(m\). 考虑求\(k\)的答案.考虑每个位置对答案的贡献,枚举位置\(i\),再枚举\(a[i]\)的值\(x\).设: \[ F(k)=\su ...

  8. NO23 Linux正则表达式结合三剑客企业级实践--取IP

    企业实践: 一.取IP的方法(用三剑客): grep: awk: sed:虽有三种,但是思路是一样的,用到正则有些表达细节不一样而已. 分析: sed***: 课堂试题: |sed -nr 's#^. ...

  9. js 转换时间戳为时间格式并且按指定格式输出

    /** * 时间戳转换为日期 */ function convertTimestamp(timestamp){ // 时间戳转换为日期 var d = new Date(timestamp); // ...

  10. springMVC,spring和Hibernate整合(重要)

    springMVC,spring和Hibernate整合 https://my.oschina.net/hugohxb/blog/184715 第一步:搭建一个springmvc工程,需要的jar有: ...