Codeforces Round #333 (Div. 1)--B. Lipshitz Sequence 单调栈

题意:n个点, 坐标已知,其中横坐标为为1~n。 求区间[l, r] 的所有子区间内斜率最大值的和。

首先要知道,[l, r]区间内最大的斜率必然是相邻的两个点构成的。

然后问题就变成了求区间[l, r]内所有子区间最大值的和。

这个问题可以利用单调栈来做。

每次找到当前点左面第一个大于当前值的点, 然后更新答案。 姿势很多。

 1 import java.io.BufferedInputStream;
 2 import java.io.BufferedOutputStream;
 3 import java.io.PrintWriter;
 4 import java.util.Scanner;
 5
 6
 7
 8 public class Main {
 9     static Scanner cin = new Scanner(new BufferedInputStream(System.in));
10     static PrintWriter cout = new PrintWriter(new BufferedOutputStream(System.out));
11     static final int maxn = 100005;
12     public static void main(String[] args) {
13         int []height = new int[maxn];
14         while (cin.hasNext()){
15             int n = cin.nextInt();
16             int q = cin.nextInt();
17             height[0] = 0;
18             for (int i = 1; i <= n; i++){
19                 height[i] = cin.nextInt();
20                 height[i-1] = Math.abs(height[i]-height[i-1]);
21             }
22             int []stack = new int[maxn];
23             int top = -1;
24             for (int i = 0; i < q; i++){
25                 int l = cin.nextInt();
26                 int r = cin.nextInt();
27                 long res = 0, cur = 0;
28                 top = -1;
29                 for (int j = l; j < r; j++){
30                     while (top >= 0 && height[stack[top]] <= height[j]){
31                         cur -= 1L * height[stack[top]] * (stack[top] - (top==0 ? l-1 : stack[top-1]));
32                         top--;
33                     }
34                     if (top >= 0){
35                         cur += 1L* (j - stack[top]) * height[j];
36                     }else{
37                         cur += 1L * (j - l + 1) * height[j];
38                     }
39                     stack[++top] = j;
40                     res += cur;
41                 }
42
43                 cout.println(res);
44             }
45             cout.flush();
46         }
47     }
48
49 }
时间: 2024-10-06 06:39:01

Codeforces Round #333 (Div. 1)--B. Lipshitz Sequence 单调栈的相关文章

Codeforces Round #305 (Div. 2)D---Mike and Feet(单调栈)

Mike is the president of country What-The-Fatherland. There are n bears living in this country besides Mike. All of them are standing in a line and they are numbered from 1 to n from left to right. i-th bear is exactly ai feet high. A group of bears

Codeforces Round #172 (Div. 1) BMaximum Xor Secondary 单调栈

//给一个长度为N的个不相同的序列,找出所有区间中最大值和第二大数的异或值最大的值 //对于所有区间只需要找其最大值和第二大数,所以对于很多区间的结果是重复的 //对于每一个数,它起作用的区间只有在其前面最多只有一个数是大于它的 //可以用一个单调递减栈来做,对于每一个新的数a[i],在它前面第一个大于它的数a[j] //和第二个大于它的数之间的数到a[i]的区间的数的最大值和第二大数为a[j] , a[i] //只需要找a[i],a[j]的所有区间所有情况 #include<cstdio>

Codeforces Round #604 (Div. 2) D. Beautiful Sequence(构造)

链接: https://codeforces.com/contest/1265/problem/D 题意: An integer sequence is called beautiful if the difference between any two consecutive numbers is equal to 1. More formally, a sequence s1,s2,-,sn is beautiful if |si?si+1|=1 for all 1≤i≤n?1. Trans

Codeforces Round #353 (Div. 2) A. Infinite Sequence

Vasya likes everything infinite. Now he is studying the properties of a sequence s, such that its first element is equal to a (s1 = a), and the difference between any two neighbouring elements is equal to c (si - si - 1 = c). In particular, Vasya won

Codeforces Round #266 (Div. 2) D. Increase Sequence

Peter has a sequence of integers a1,?a2,?...,?an. Peter wants all numbers in the sequence to equalh. He can perform the operation of "adding one on the segment[l,?r]": add one to all elements of the sequence with indices froml to r (inclusive).

Codeforces Round #353 (Div. 2) A. Infinite Sequence 思维题

A. Infinite Sequence time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasya likes everything infinite. Now he is studying the properties of a sequence s, such that its first element is equal

Codeforces Round #277 (Div. 2) LIS of Sequence Dp

题意: 给出一个序列,问每个位置的元素,分别属于哪一类的东西.第一类 没有出现在任何的上升子序列中. 第三类 出现在所有上升子序列中 .第二类 就是剩下的了.. 求两个东西 ,  dp[i] 表示 从1到 i 最长上升子序列的长度,dp1[i]表示从i到n 最长上升子序列的长度. 设原序列最长上升子序列长度为len 1. 若dp[i]+dp1[i] - 1 != len , 他就属于第一类. 2. 若 t  = dp[i] 的 t 出现了不止一次,且不属于第一类,那他就是第二类. 剩下的就是第三

Codeforces Round #333 (Div. 2)

因为现在太渣了只能做div2:争取每次div2都做出4题,然后提高自己能力之后,再来个5题全过,所以下面只有四题的题解: 题A 题意:给你两个数,但是用的是数组来表示,每个数有n个数,然后有一个基数base,也就是base进制的意思,然后问你这两个数那个比较大. 题解:水题,直接开龙龙模拟 1 /*zhen hao*/ 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 typedef long long ll; 6 int val[50

Codeforces Round #529 (Div. 3) E. Almost Regular Bracket Sequence (思维)

Codeforces Round #529 (Div. 3) 题目传送门 题意: 给你由左右括号组成的字符串,问你有多少处括号翻转过来是合法的序列 思路: 这么考虑: 如果是左括号 1)整个序列左括号个数比右括号多 2 2)在这个位置之前,所有位置的前缀左括号个数都不少于前缀右括号个数 3)在这个位置和这个位置之后,在修改后所有位置的前缀左括号个数减去前缀右括号个数大于2 (这里这么想,把左变成右,左-1,右+1) 右括号也是这样 代码: #include<bits/stdc++.h> usi