NOI模拟(3.3)螺旋序列

Description

S也想寻求真正的智慧,然而由于“抑制力”的存在,她必须先解决一系列询
问。
有一个长度为n的序列a,一个长度为m序列b被称为螺旋序列当且仅当
b1=bm且对于1<=i<=m有bi<=b1。
S需要回答q个询问,每个询问用l,r两个参数描述,表示询问区间[l,r]的最长
连续子螺旋序列的长度。

Input

第一行两个整数n,q,表示序列长度和询问数。
第二行n个整数ai表示序列a。
以下q行,每行两个整数l,r表示一次询问。

Output

对每次询问输出一行一个整数表示最大连续螺旋序列的长度。

Sample Input

5 3
3 2 1 2 3
1 4
2 5
1 5

Sample Output

3
3
5

Data Constraint

本题采用捆绑测试,只有通过一个子任务的全部数据才能得到该子任务分
数,否则不得分。
子任务1(20分):n,m<=10
子任务2(20分):n,m<=1000
子任务3(20分):n,m<=2*10^5,1<=ai<=10
子任务4(40分):n,m<=5*10^5;|ai|<=10^9

Solution

30分的裸暴力

离散化相等的数字,做一个链表,st表处理区间最大值,对每个询问都暴力去跳

#include <map>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rg register

template<class T> inline T dma(rg T x,rg T y) {return x>y?x:y;}
template<class T> inline void read(rg T &x)
	{
	rg int c=getchar();rg bool b=0;
	for(;c<48||c>57;c=getchar())
		if(c==45)b=1;
	for(x=0;c>47&&c<58;c=getchar())
		x=(x<<1)+(x<<3)+c-48;
	if(b)x=-x;
	}

const int N=500010;
std::vector<int>vc;
std::map<int,int>hc;
int n,q,seq[N],fir[N],nex[N],st[20][N],bin[20],lgg[20],ans;

void sequence_table()
	{
	lgg[0]=-1;for(rg int i=1;i<=n;i++)lgg[i]=lgg[i>>1]+1;
	for(rg int i=0;i<20;i++)bin[i]=1<<i;
	for(rg int i=1;i<=n;i++)st[0][i]=seq[i];
	for(rg int t=1;t<20;t++)
		for(rg int i=1;i<=n;i++)
			if(i+bin[t]-1<=n)st[t][i]=dma(st[t-1][i],st[t-1][i+bin[t-1]]);
	}

int sequence_query(rg int x,rg int y)
	{
	rg int t=lgg[y-x+1];
	return dma(st[t][x],st[t][y-bin[t]+1]);
	}

void jump(rg int x,rg int lim)
	{
	for(rg int rig=x,lef=nex[x];lef>=lim;lef=nex[lef])
		{
		while(rig>lef&&sequence_query(lef,rig)>seq[lef])rig=nex[rig];
		ans=dma(ans,rig-lef+1);
		}
	}

int main()
	{
	freopen("sequence.in","r",stdin);
	freopen("sequence.out","w",stdout);
	read(n),read(q);
	for(rg int i=1;i<=n;i++)
		{
		read(seq[i]);
		vc.push_back(seq[i]);
		}
	std::sort(vc.begin(),vc.end());
	vc.erase(std::unique(vc.begin(),vc.end()),vc.end());
	for(rg int i=0;i<vc.size();i++)
		hc[vc[i]]=i+1;
	for(rg int i=1;i<=n;i++)seq[i]=hc[seq[i]];
	memset(fir,-1,sizeof fir);
	for(rg int i=1;i<=n;i++)
		{
		nex[i]=fir[seq[i]];
		fir[seq[i]]=i;
		}
	sequence_table();
	for(rg int x,y;q;q--)
		{
		ans=1;
		read(x),read(y);
		for(rg int i=y;i>=x;i--)
			jump(i,x);
		printf("%d\n",ans);
		}
	fclose(stdin);
	fclose(stdout);
	return 0;
	}

  

时间: 2024-12-21 05:15:29

NOI模拟(3.3)螺旋序列的相关文章

【基础练习】【数论/模拟】codevs1670 无穷的序列题解

文章被盗还是很严重,加版权信息 转载请注明出处 [ametake版权所有]http://blog.csdn.net/ametake欢迎来看看 题目: 题目描述 Description 有一个无穷序列如下: 110100100010000100000- 请你找出这个无穷序列中指定位置上的数字 输入描述 Input Description 第一行一个正整数N,表示询问次数: 接下来的N行每行一个正整数Ai,Ai表示在序列中的位置. 输出描述 Output Description N行,每行为0或1,

【NOI模拟赛(湖南)】DeepDarkFantasy

DeepDarkFantasy 从东京出发,不久便到一处驿站,写道:日暮里.  ——鲁迅<藤野先生> 定义一个置换的平方为对1~n的序列做两次该置换得到的序列.已知一个置换的平方,并且这个结果是一个排列,求该置换. 输入第一行一个数n表示排列长度,接下来一行n个数描述排列. 有解则输出一行n个数表示原排列.否则输出一行一个-1. 测试点编号 特征 0~1 n<=10 2~9 n<=1000000 [题解] 注:由于置换和排列在数学表现形式上是一样的,于是下文不对此进行详细区分. 首

【NOIP2017模拟8.5】序列问题

Description Input 输入文件名为seq.in.首先输入n.接下来输入n个数,描述序列 A. Output 输出文件名为seq.out.输出一行一个整数代表答案. Sample Input 7 0 35 40 45 56 65 94 Sample Output 66636 Data Constraint 对于30%的数据,n<=5000对于60%的数据,n<=50000对于100%的数据,n<=500000,0<=A[i]<=10^9 ST加暴力枚举区间显然过不

NOIP模拟题——Mushroom的序列

Mushroom的序列[问题描述]Mushroom手中有n个数排成一排,现在Mushroom想取一个连续的子序列,使得这个子序列满足:最多只改变一个数,使得这个连续的子序列是严格上升子序列,Mushroom想知道这个序列的最长长度是多少.[输入格式]第一行一个整数n,表示有n个数.第二行为n个数.[输出格式]一个数,为最长长度.[输入样例]67 2 3 1 5 6[输出样例]5[样例解释]选择第2个数到第6个数,把1改变成4即可.[数据范围]对于30%的数据,n<=10对于60%的数据,n<=

NOI模拟(3.6)Assignment

Description 随机生成一个长度为m且每个元素都为1~n之间的整数的单调不下降序列~(即序列的(i>1)都不小于),(随机生成指每一种可能的序列都等概率被生成).请问这个序列的众数出现次数期望是多少,有多组数据. Input 第一行一个整数T,为数据组数 接下来T行,每行两个被空格隔开的正整数m,n为序列长度和元素的值的上界. Output 一共T行,每一行一个实数,为每组数据的答案 如果你的答案与标准答案的误差不超过1e-5,则视为正确 Sample Input 4 1 5 3 3 2

NOI模拟赛 Day1

[考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧张起来!!! 好了不扯淡了...

2017级算法模拟上机准备篇(序列DP 进阶_1)

进阶版的序列DP 从一道题的优化开始 ModricWang的序列问题 题目描述:给定一个序列,求出这个序列中的最长上升子序列的长度. 这道题的本质还是求解一个最长上升子序列的问题 相对与之前提到过的O(n^2)的算法 我们可以重新整理思路 用O(nlogn)的思路来写,用贪心和二分优化之前的算法 我们设置新的DP数组//dp[i]代表的是当前长度为i的上升子序列的末尾元素的大小 状态转移方程为如果dp[len] < ar[i] 那么就将数ar[i]加到dp数组尾部. 反之,说明可以继续优化,显然

繁华模拟赛 Evensgn玩序列

#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> using namespace std; const int maxn = 5000; int n,a[maxn],b[maxn],c[maxn],rka[maxn],rkb[maxn],rkc[maxn]; bool visa[maxn],visb[maxn],vi

NOI模拟赛Day2

深深的感受到了自己的水 -------------------------------------------------------------------------------------------------------------------------- T1: 题意:一棵树,有k个关键点,求分成连通块,每块至少一个关键点,使连通块最大最小. woc我为啥没想到二分,不懂啊,考试的时候是在梦游吗 二分后判断是否可行 就是一个简单的树上的贪心 可以先bfs一遍倒着来,max表示改点最