HackerRank - almost-sorted-interval (思维)
2017-02-23 10:09
330 查看
题意:题意非常简单,给你n个数,范围都是1-n,问你这个序列中有多少个区间满足最小值在最左边,最大值在最右边
思路:想了一个下午。。好久没做题感觉要eat shit了。。
假设我们从左往右扫过去,我们考虑维护两个序列以及它们的贡献值,一个为当前数字左边已合并区间的最小值,一个为当前数字左边已合并区间的最大值,设一个为s1,一个s2,那么比如我出一个样例为 1 2 4 3 5
合并的过程为,首先扫到1,把1添加进s1,s2,因为当前只有你一个所以最大最小值都是你了,当扫到2的时候,因为s1中的1比2小,所以最小值满足了条件,然后看最大值s2序列,也满足1<2,所以1和2是可以合并的,此时我们把序列s2中的1删除,放入2,因为考虑右边的数字往左合并的时候必须满足最大值要比2大,所以既然大于2,那么也就大于1,而对于s1序列中的1是不用删除的,因为考虑右边的数字往左合并的时候它可以合并到2这里,也可以合并到1这里,那么对于数字2的贡献值就要加上1的贡献值,此时答案就是1+2,
然后扫到4,由于同样满足上述的过程,所以此时s1有1,2,4 ,s2序列中有4,此时答案为1+2+3
然后扫到3这个数字,由于3是比4要小的,所以3是显然不能和4合并在一起,所以我们要将4的贡献值-1,并且更新s1,把4弹出,放入3,同样的s2中的4要比3大,故不能合并,此时的s2应该有4,3两个元素,理由和s1中有多个的原因是雷同的,此时答案是1+2+3 +1
最后扫到5这个数字,由于满足3比5小,最小值满足条件,然后看s2中尾是3,满足3<5,故是可以合并的,此时对于5的贡献值就要加上3的贡献值,然后再看s2中的4,也满足4<5,故4和5也是可以合并在一起的,所以5的贡献值还要加上4的贡献值,此时答案为1+2+3+1+4 = 11 那么这道题大概的流程就是这样了,非常的神奇的一个O(n)的做法
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
#define LL long long
vector<int> mins;
vector<int> maxs;
int a[maxn];
int num[maxn];
LL ans = 0;
void maintainmins(int i)
{
if(mins.empty())
mins.push_back(a[i]);
else
{
int tmp = mins.back();
while(tmp > a[i])
{
num[maxs.back()]--;
if(!num[maxs.back()]) maxs.pop_back();
mins.pop_back();
if(mins.empty())break;
tmp = mins.back();
}
mins.push_back(a[i]);
}
}
void maintainmaxs(int i)
{
int tmp = maxs.back();
while(tmp < a[i])
{
num[a[i]]+=num[tmp];
maxs.pop_back();
if(maxs.empty())break;
tmp = maxs.back();
}
maxs.push_back(a[i]);
ans+=num[a[i]];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<=n;i++)
num[i]=1;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i = 1;i<=n;i++)
{
maintainmins(i);
if(maxs.empty())
{
ans++;
maxs.push_back(a[i]);
continue;
}
maintainmaxs(i);
}
printf("%lld\n",ans);
return 0;
}
HackerRank - almost-sorted-interval
思路:想了一个下午。。好久没做题感觉要eat shit了。。
假设我们从左往右扫过去,我们考虑维护两个序列以及它们的贡献值,一个为当前数字左边已合并区间的最小值,一个为当前数字左边已合并区间的最大值,设一个为s1,一个s2,那么比如我出一个样例为 1 2 4 3 5
合并的过程为,首先扫到1,把1添加进s1,s2,因为当前只有你一个所以最大最小值都是你了,当扫到2的时候,因为s1中的1比2小,所以最小值满足了条件,然后看最大值s2序列,也满足1<2,所以1和2是可以合并的,此时我们把序列s2中的1删除,放入2,因为考虑右边的数字往左合并的时候必须满足最大值要比2大,所以既然大于2,那么也就大于1,而对于s1序列中的1是不用删除的,因为考虑右边的数字往左合并的时候它可以合并到2这里,也可以合并到1这里,那么对于数字2的贡献值就要加上1的贡献值,此时答案就是1+2,
然后扫到4,由于同样满足上述的过程,所以此时s1有1,2,4 ,s2序列中有4,此时答案为1+2+3
然后扫到3这个数字,由于3是比4要小的,所以3是显然不能和4合并在一起,所以我们要将4的贡献值-1,并且更新s1,把4弹出,放入3,同样的s2中的4要比3大,故不能合并,此时的s2应该有4,3两个元素,理由和s1中有多个的原因是雷同的,此时答案是1+2+3 +1
最后扫到5这个数字,由于满足3比5小,最小值满足条件,然后看s2中尾是3,满足3<5,故是可以合并的,此时对于5的贡献值就要加上3的贡献值,然后再看s2中的4,也满足4<5,故4和5也是可以合并在一起的,所以5的贡献值还要加上4的贡献值,此时答案为1+2+3+1+4 = 11 那么这道题大概的流程就是这样了,非常的神奇的一个O(n)的做法
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
#define LL long long
vector<int> mins;
vector<int> maxs;
int a[maxn];
int num[maxn];
LL ans = 0;
void maintainmins(int i)
{
if(mins.empty())
mins.push_back(a[i]);
else
{
int tmp = mins.back();
while(tmp > a[i])
{
num[maxs.back()]--;
if(!num[maxs.back()]) maxs.pop_back();
mins.pop_back();
if(mins.empty())break;
tmp = mins.back();
}
mins.push_back(a[i]);
}
}
void maintainmaxs(int i)
{
int tmp = maxs.back();
while(tmp < a[i])
{
num[a[i]]+=num[tmp];
maxs.pop_back();
if(maxs.empty())break;
tmp = maxs.back();
}
maxs.push_back(a[i]);
ans+=num[a[i]];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<=n;i++)
num[i]=1;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i = 1;i<=n;i++)
{
maintainmins(i);
if(maxs.empty())
{
ans++;
maxs.push_back(a[i]);
continue;
}
maintainmaxs(i);
}
printf("%lld\n",ans);
return 0;
}
Almost sorted interval
HackerRank - almost-sorted-interval
相关文章推荐
- hackerrank:Almost sorted interval
- hakerrank Almost sorted interval 单调队列
- HackerRank - Almost Sorted
- hdu 5532 Almost Sorted Array【思维+模拟】
- Almost sorted interval
- 【Hackerrank】Merge two sorted linked lists
- 【Hackerrank】Delete duplicate-value nodes from a sorted linked list
- duoj Almost sorted interval 单调队列
- 【数学思维 && ax + by = n 给你n让你求有多少对(a,b) a<b 满足方程其中x,y是正整数】HackerRank Satisfactory Pairs
- HDU 5532 Almost Sorted Array(思维,最长递增子序列,模拟)
- 【Hackerrank】Insert a node into a sorted doubly linked list
- 【HackerRank】Fair Cut(DP)
- 【hackerrank】World CodeSprint 11 T4
- HDU 5532——Almost Sorted Array——————【技巧】
- HackerRank "Lena Sort"
- Hackerrank Coprime Conundrum
- hackerrank Ticket
- Codeforces 822 C. Hacker, pack your bags! 思维
- hackerrank-2D Array - DS
- Hackerrank 101 Hack 42 Array Pairs