【问题述】

给出一个随机的排列,请你计算最大值减最小值的差小于等于0~n-1的区间分别有多少个。

输入格式

输入文件名为sum.in。

第一行一个数T(<=10),表示数据组数

对于每一组数据:

第一行一个数n(1<=n<=100,000)

第二行n个数a1...an,表示一个随机的排列

【输出】

输出文件名为sum.out。

对于每组数据输出n行,分别表示差值小于等于0~n-1的区间个数

【输入输出样例】

sum.in

sum.out

1

4

3 2 4 1

4

5

7

10

【数据说明】

对于30%的数据,1<=n<=300;

对于60%的数据,1<=n<=5000

对于100%的数据,1<=n<=100000

分析:考虑暴力,O(n^2)枚举区间,O(n)求最值,可以过30分.

如何把n^3优化到n^2?我们可以在找最值的时候优化一下,我们并不一定非要在固定了区间后再去找最值然后更新当前区间,而是我们先固定左端点,然后从左往右扩展去找最值,用最值更新区间信息.

比如,我们已经求得当前区间的最小值minx和最大值maxx,向右扩展一位得到新的minx和maxx,那么ans[maxx - minx]++.当然,我们也可以用ST表O(1)维护最值,复杂度也是O(n^2)的.

题目数据范围很明显提示复杂度要O(nlogn),考虑怎么优化60分的算法.我们向右跳并不需要每次只跳一位,因为可能有很多位置不会更新minx和maxx,我们需要找到下一位能更新minx和maxx的位置,利用单调栈来记录.维护一个单调上升的单调栈和一个单调下降的.因为这是一个随机的排列,所以差不多会跳logn次.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; int T,n,a[],nextmin[],nextmax[],head,pos[],p[],minx,maxx;
long long ans[]; int main()
{
scanf("%d", &T);
while (T--)
{
memset(ans, , sizeof(ans));
memset(a, , sizeof(a));
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d", &a[i]);
for (int i = ; i <= n; i++)
nextmin[i] = nextmax[i] = n + ;
head = ;
memset(p, , sizeof(p));
for (int i = ; i <= n; i++)
{
while (head > && a[i] < p[head])
{
nextmin[a[pos[head]]] = i;
head--;
}
p[++head] = a[i];
pos[head] = i;
}
memset(pos, , sizeof(pos));
head = ;
memset(p, 0x3f3f3f, sizeof(p));
for (int i = ; i <= n; i++)
{
while (head > && a[i] > p[head])
{
nextmax[a[pos[head]]] = i;
head--;
}
p[++head] = a[i];
pos[head] = i;
}
for (int i = ; i <= n; i++)
{
minx = maxx = a[i];
int j = i;
while (j <= n)
{
if (nextmax[maxx] < nextmin[minx])
{
ans[maxx - minx] += nextmax[maxx] - j;
j = nextmax[maxx];
maxx = a[nextmax[maxx]];
}
else
{
ans[maxx - minx] += nextmin[minx] - j;
j = nextmin[minx];
minx = a[nextmin[minx]];
}
}
}
for (int i = ; i < n; i++)
ans[i] += ans[i - ];
for (int i = ; i < n; i++)
printf("%lld\n", ans[i]);
} return ;
}

noip模拟赛 排列的更多相关文章

  1. CH Round #54 - Streaming #5 (NOIP模拟赛Day1)

    A.珠 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2354%20-%20Streaming%20%235%20(NOIP模拟赛Day1)/珠 题解:sb题, ...

  2. 2016-06-19 NOIP模拟赛

          2016-06-19 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c ...

  3. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  4. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  5. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  6. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  7. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  8. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  9. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

随机推荐

  1. bzoj 1026: [SCOI2009]windy数【数位dp】

    忘记limit不能记WA了一发-- 典型数位dp,变成work(r)-work(l-1),然后dfs的时候记录w当前位置,la上一个数选的什么,lm当前位是否有上限,ok当前位是否可以不考虑差大于等于 ...

  2. bzoj 1650: [Usaco2006 Dec]River Hopscotch 跳石子【贪心+二分】

    脑子一抽写了个堆,发现不对才想起来最值用二分 然后判断的时候贪心的把不合mid的区间打通,看打通次数是否小于等于m即可 #include<iostream> #include<cst ...

  3. less新手入门(五)—— CssGuards、循环、合并

    九. CssGuards 警卫也可以应用于css选择器,这是一种语法糖,用于声明mixin,然后立即调用它. 例如,在1.5.0之前,您必须这样做 .my-optional-style() when ...

  4. ASP.Net 知识点总结(三)

    1.描述一下C#中索引器的实现过程,是否只能根据数字进行索引? 答:不是.可以用任意类型. 2.<%# %> 和 <% %> 有什么区别? 答:<%# %>表示绑定 ...

  5. ACM博弈论总结

    一.Bash博弈 1.问题模型:只有一堆n个物品,两人轮流从这堆物品中取物,最多取m个,最后取光者胜. 2.解决思路:当n=m+1时,由于一次最多取m个,无论先取者拿走多少个,后取者都能一次拿走剩余的 ...

  6. 状态压缩+枚举 UVA 11464 Even Parity

    题目传送门 /* 题意:求最少改变多少个0成1,使得每一个元素四周的和为偶数 状态压缩+枚举:枚举第一行的所有可能(1<<n),下一行完全能够由上一行递推出来,b数组保存该位置需要填什么 ...

  7. 274 H-Index H指数

    给定一位研究者的论文被引用次数的数组(被引用次数是非负整数).写一个方法计算出研究者的H指数.H-index定义: “一位科学家有指数 h 是指他(她)的 N 篇论文中至多有 h 篇论文,分别被引用了 ...

  8. Java 8 (11) 新的日期和时间API

    在Java 1.0中,对日期和时间的支持只能依赖java.util.Date类.这个类只能以毫秒的精度表示时间.这个类还有很多糟糕的问题,比如年份的起始选择是1900年,月份的起始从0开始.这意味着你 ...

  9. 【JAVA 学习笔记2】if使用例子

    int a =3; if (a%2==0) { System.out.println(a+" 是偶数"); System.out.println(a+" 不是奇数&quo ...

  10. STA之Concepts (2)

    3 Skew between signals Skew is the difference in timing between two or more signals, maybe data, clo ...