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 = ;
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的更多相关文章
- XTUOJ 1205 Range
Range Time Limit : 1000 MS Memory Limit : 65536 KB Problem Description For an array, the range funct ...
- SQL Server 合并复制遇到identity range check报错的解决
最近帮一个客户搭建跨洋的合并复制,由于数据库非常大,跨洋网络条件不稳定,因此只能通过备份初始化,在初始化完成后向海外订阅端插入数据时发现报出如下错误: Msg 548, Level 16, S ...
- Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range
在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...
- [LeetCode] Range Addition 范围相加
Assume you have an array of length n initialized with all 0's and are given k update operations. Eac ...
- [LeetCode] Count of Range Sum 区间和计数
Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...
- [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 ...
- [LeetCode] Range Sum Query - Mutable 区域和检索 - 可变
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- [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 ...
- [LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
随机推荐
- Random Variables
可测空间(Measurable Space)和测度空间(Measure Space) 集合X,X上的一个σ-algebra A,则(X,A)被称为可测空间(measurable space) 再在A上 ...
- 六、java基础-单例模式_继承_覆盖_多态
1.单例模式: 1)提出原因 是由gof 也就是四人组提出来的.为了保证jvm中某一类型的java对象永远只有一个,同时也是为了节省内存的开销.因为外面程序可以通过new的方法直接调用类里面的构造方法 ...
- GeoDa绘制疫情地图
刚学习GeoDa,菜鸟,目前还不能在地图上显示省市名称,求教. 看到丁香医生发布的疫情地图,我也尝试做一下,不过我的shp文件上只有中国大陆的31个省市. 数据来源于丁香医生,截至时间为 2020.1 ...
- ch7对表单和数据表格使用样式
对数据表格应用样式 1.表格特有的元素 caption:基本上用做表格的标题.summary:可应用于表格的标签,用来描述表格的内容(与image的alt文本相似) <table class=& ...
- priority_queue优先级队列总结
http://www.cppblog.com/Darren/archive/2009/06/09/87224.html priority_queue用法 priority_queue 调用 STL里面 ...
- CH11 关联容器
关联容器与顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的,而顺序容器是按它们在容器中的位置来顺序保存和访问的.两个主要的关联容器:map和set map 中的元素的是一个key-va ...
- app开屏广告
最近公司有个需求需要做app开屏广告(跳转到不同的页面)--下面是app开屏广告的处理 1.管理后台效果图 (1)广告链接--商品详情 (2)广告链接--关联模块 (3)广告链接--消息富文本 (4) ...
- OpenJ_Bailian - 1088 滑雪(记忆化搜索)
题意:给定一个二维数组,一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小,输出可以滑行的最长区域的长度. 分析:对于每一个点,进行记忆化搜索.若某点可以向四周某几个点滑行,记忆化搜索求出 ...
- 解决win10创建Django工程,运行django-admin.py startproject 工程名,失败的问题
在看我这篇教程的前提是你应该已经正确装好python和Django了,好了,废话不说了,正题走你!你现在是不是很纠结自己运行django-admin.py startproject 工程名 ...
- JS取整方法
1.toFixed方法 定义:toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 例如:将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学 ...