POJ 2452 Sticks Problem (暴力或者rmq+二分)
题意:给你一组数a[n],求满足a[i] < a[k] < a[j] (i <= k <= j)的最大的 j - i 。
析:在比赛时,我是暴力做的,虽然错了好多次,后来说理解是rmq,我又用rmq写了一次,发现rmq还没有我暴力快,rwq 2000多,暴力才700.
暴力中加了一个优化条件就是前枚举 i 时,下一个 i 值不一定是i+1,而是满足条件中的最大值的位置。这样优化就是时间很短了。
如果用rmq,就得用两个dp数组分别记录最大值和最小值的下标,然后枚举 i,在i+1 - n-1这个区间中求第一个小于 a[i] 的数,然后再从 i+1 - 该数,
求最大的那个数的下标。不断更新答案即可。
代码如下:
暴力的代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define debug puts("+++++")
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 5e4 + 5;
const LL mod = 1e9 + 7;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }
inline int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }
inline int lcm(int a, int b){ return a * b / gcd(a, b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
int a[maxn]; int main(){
while(scanf("%d", &n) == 1){
for(int i = 0; i < n; ++i) scanf("%d", a+i);
int ans = 0;
int x;
for(int i = 0; i < n-ans; i = x+1){
x = Min(x, a[i]);
int mmax = a[i];
x = i;
for(int j = i+1; j < n; ++j){
if(mmax < a[j]){
x = j;
mmax = a[j];
}
if(a[j] < a[i]) break;
if(mmax <= a[j]){ ans = Max(ans, j-i); }
}
}
printf("%d\n", ans ? ans : -1);
}
return 0;
}
rmq的代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 5e4 + 5;
const LL mod = 10000000000007;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m; }
int dp1[maxn][20], dp2[maxn][20];
int a[maxn];
inline int Min_(int i, int j){ return a[i] < a[j] ? i : j; }
inline int Max_(int i, int j){ return a[i] < a[j] ? j : i; } void rmq_init(){
for(int i = 0; i < n; ++i) dp1[i][0] = dp2[i][0] = i;
for(int j = 1; (1<<j) <= n; ++j)
for(int i = 0; i + (1<<j) - 1 < n; ++i){
dp1[i][j] = Min_(dp1[i][j-1], dp1[i+(1<<(j-1))][j-1]);
dp2[i][j] = Max_(dp2[i][j-1], dp2[i+(1<<(j-1))][j-1]);
}
} inline int rmqmin(int l, int r){
int k = (int)(log(r-l+1.0) / log(2.0));
return Min_(dp1[l][k], dp1[r-(1<<k)+1][k]);
} inline int rmqmax(int l, int r){
int k = (int)(log(r-l+1.0) / log(2.0));
return Max_(dp2[l][k], dp2[r-(1<<k)+1][k]);
} int solve(int i){
int l = i+1, r = n-1;
while(l < r){
int mid = (l+r) >> 1;
if(a[rmqmin(l, mid)] > a[i]) l = mid + 1;
else r = mid;
}
return rmqmax(i, l);
} int main(){
while(scanf("%d", &n) == 1){
for(int i = 0; i < n; ++i) scanf("%d", a+i);
rmq_init();
int ans = 0;
for(int i = 0; i < n - ans - 1; ++i){
int j = solve(i);
ans = Max(ans, j-i);
}
printf("%d\n", ans ? ans : -1);
}
return 0;
}
POJ 2452 Sticks Problem (暴力或者rmq+二分)的更多相关文章
- POJ 2452 Sticks Problem
RMQ+二分....枚举 i ,找比 i 小的第一个元素,再找之间的第一个最大元素..... Sticks Problem Time Limit: 6000MS ...
- POJ_2452 Sticks Problem 【ST表 + 二分】
一.题目 Sticks Problem 二.分析 对于$i$和$j$,并没有很好的方法能同时将他们两找到最优值,所以考虑固定左端点$i$. 固定左端点后,根据题意,$a[i]$是最小值,那么现在的问题 ...
- *HDU3486 RMQ+二分
Interviewe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 搜索 + 剪枝 --- POJ 1101 : Sticks
Sticks Problem's Link: http://poj.org/problem?id=1011 Mean: http://poj.org/problem?id=1011&lan ...
- Sticks Problem
Sticks Problem poj-2452 题目大意:给你一串n个数的数列a,上面的数为a1到an.我们求最大的y-x,其中,y和x满足1.x<y 2.任意的x<i<y,都有ai ...
- hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数 ...
- hdu 3486 Interviewe (RMQ+二分)
Interviewe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- POJ 2723 Get Luffy Out(2-SAT+二分答案)
Get Luffy Out Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8851 Accepted: 3441 Des ...
- HDU 5089 Assignment(rmq+二分 或 单调队列)
Assignment Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
随机推荐
- 集训第五周动态规划 H题 回文串统计
Hrdv is interested in a string,especially the palindrome string.So he wants some palindrome string.A ...
- node学习的一些网站
Node.js 包教不包会 篇幅比较少 node express 入门教程 nodejs定时任务 一个nodejs博客 [NodeJS 学习笔记04]新闻发布系统 过年7天乐,学nodejs 也快乐 ...
- BNUOJ 3278 Candies
Candies Time Limit: 1500ms Memory Limit: 131072KB This problem will be judged on PKU. Original ID: 3 ...
- Leetcode 166.分数到小数
分数到小数 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数. 如果小数部分为循环小数,则将循环的部分括在括号内. 示例 1: 输入: num ...
- noip模拟赛 分组
分析:暴力分挺多,也挺好想的,个人感觉两个特殊性质没什么卵用. 对于K=1,n ≤ 1024的情况,从后往前贪心地分,如果能和上一组分在一起就分在一起,否则就再开一组,这样可以保证字典序最小.ai ≤ ...
- 2017 CCPC 杭州 HDU6265B 积性函数
题目链接 http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf B题 数论题 h(n)=∑ d|n φ(d) × ...
- git一个本地仓库连接多个远程仓库
前言:由于公司的GIT是内网服务器,而在家工作访问不了内网服务器,由此想把本地仓库连接一个外网的GIT服务器(码云),方便不在公司时开发. 原文 某些场合,一个git项目需要能同时使用两个甚至多个远程 ...
- Redis的集群方案之Sentinel(哨兵模式)(待实践)
哨兵模式是主从切换的一种方案,但是可以借助此方案实现集群,达到高可用. 先收集教程,待实践. 参考: https://redis.io/topics/sentinel(官方文档) http://ife ...
- NetworkManager的坑(如何让network manager不去管理网络端口)
在CentOS上,有时你需要停止并禁用 NetworkManager.但这样做了之后,其实NetworkManager还在影响着你的端口. 比如你有端口配置如下: [root@compute02 ~] ...
- sdfs
<!DOCTYPE html><html><head><meta charset="GB18030"><title>In ...