noip模拟赛 排列
【问题描述】
给出一个随机的排列,请你计算最大值减最小值的差小于等于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模拟赛 排列的更多相关文章
- 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题, ...
- 2016-06-19 NOIP模拟赛
2016-06-19 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
随机推荐
- c++ gets函数
函数名称:gets函数 函数结构:gets() 所需头文件:#include<cstdio> 函数作用:持续读入,直到遇到换行停止输出.
- WKWebView 和 UIWebView 允许背景音乐自动播放(记录)
WKWebView WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; config.allowsInlin ...
- linux rpm 安装
1.rpm 安装rpm -ivh package_name-i:install的意思-v:查看更详细的安装信息-h:以安装信息栏显示安装进度rpm -ivh package_name --test 2 ...
- ORACLE_AQ 队列
Oracle AQ Demo,Step by Step 我准备用AQ来做一个数据仓库系统,提交分析任务队列.有以下需求: 1.利用通知异步的执行存储过程 2.设定队列大小极限 3.出列即删除 OK,l ...
- C# 访问mongodb数据库
1.引用四个mongodb动态库MongoDB.Bson.dll,MongoDB.Driver.Core.dll,MongoDB.Driver.dll,MongoDB.Driver.Legacy.dl ...
- Selenium 进行参数化
Selenium参数化分为大小: 小:list.dict.函数 大:txt.excel.mysql.redis 哪种方式使自己的工作简单高效就选那种!!! Selenium进行参数化有多种形式: 本文 ...
- java多线程(线程通信-等待换新机制-代码优化)
等待唤醒机制涉及方法: wait():让线程处于冻结状态,被wait的线程会被存储到线程池中. noticfy():唤醒同一个线程池中一个线程(任意也可能是当前wait的线程) notifyAll() ...
- CAD创建组(网页版)
主要用到函数说明: _DMxDrawX::CreateGroup 创建组.如果组名已经存在,就把实体加入组中.详细说明如下: 参数 说明 BSTR pszName 组名.,如果为空,创建匿名组 IDi ...
- 梦想CAD控件COM接口光栅图处理
在CAD操作过程中,我们在设计绘图时,光栅图像也就是我们常说的图片,应用非常广泛,在CAD中可以直接插入光栅图像,并且可以对光栅图像进行裁剪.透明度调整等一些操作,在网页可以快速实现我们所需功能. 一 ...
- Gitlab forbidden
搭建使用了两年的gitlab 抽风了居然forbidden # vim /etc/gitlab/gitlab.rb gitlab_rails['rack_attack_git_basic_auth'] ...