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 ...
随机推荐
- delphi中的pansichar和pchar等类型的区别
varc: Char; {Char 类型的取值范围是: #0..#255, 用十六进制表示是: #$0..#$FF}begin{用十进制方式赋值:}c := #65;ShowMessage(c); { ...
- 记录一次Git远程仓库版本回退
操作过程: 首先查看远程仓库版本,如下图所见,最近一次提交为2018-03-19 22:16:25 第一步:使用git log命令查看历史提交记录,选择要回退的版本号,commit后面一串字符,这里我 ...
- Java的clone方法效率问题
在Java中,经常会需要新建一个对象,很多情况下,需要这个新建的对象和现有的某个对象保持属性一致. 那么,就有两种方式来实现这个对象的构造: ①通过新建一个对象,为这个对象的属性根据原有对象的属性来进 ...
- Day2-O-Coloring a Tree CodeForces-902B
You are given a rooted tree with n vertices. The vertices are numbered from 1 to n, the root is the ...
- express写的接口在疯狂刷新几十次后,服务器挂掉
用到的命令行: show status like 'Threads%'; show variables like '%max_connections%'; show global status lik ...
- JAVA地址栏重写很详细
这几天蛋疼.看看别人url重写是怎么搞的..1.解释下什么事url重写,以及它的优缺点: URL重写,其实就是把带一大堆参数的url,变成一个看上去很规矩的url.例:/viewthread.jsp? ...
- 算法:辗转相除法求最大公约数(C语言实现)
辗转相除法,一种求最大公约数的算法 已知:A / B = C ······ R (A.B.C.R皆是整数) 假设:D是A的余数,D也是B的余数,那么D就是A和B的公约数 D是A和B的约数,则A和B是 ...
- 吴裕雄--天生自然JAVA数据库编程:使用元数据分析数据库
import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import j ...
- swoole之异步文件IO
一.代码部分 读: <?php /** * 异步文件系统仅限于4.3.0之前的版本 * 读取文件 */ $filename = dirname(__FILE__).DIRECTORY_SEPAR ...
- OpenWRT飞行计划
openwsn飞行计划 工程wiki http://openwsn-berkeley.github.io/firmware/ 2015-12-30 Openwrt 预备 openwrt 未整理 小神器 ...