首页 > 其他分享 >P7809 [JRKSJ R2] 01 序列 题解

P7809 [JRKSJ R2] 01 序列 题解

时间:2023-08-29 23:44:53浏览次数:36  
标签:01 log R2 int 题解 sum IO using

对于第二种操作,很容易想到只有 \(1\) 或 \(2\) 两种答案,若该区间内存在 \(01\) 这个子序列,那么答案为 \(2\) 反之为 \(1\).可以通过对该 \(01\) 串做一个前缀和,若出现 \(01\) 这个子序列就累加,最后判断左右端点是否相等即可,时间复杂度 \(O(n)\).

对于第一种操作,\(\text{Subtest 1}\) 很明显答案为 \(r-l+1\).

然后考虑正解,很明显该最长不下降子序列形如 \(0,0,0,\dots,1,1,1\),即由若干个连续的 \(0\) 和若干个连续的 \(1\) 构成,基于这一点,我们可以做一个前缀和,统计到 \(i\) 时 \([1,i]\) 中 \(0\) 和 \(1\) 的数量,那么答案就是 \(\max^r_{i=l} sum_{i,0}-sum_{l-1,0}+sum_{r,1}-sum_{i-1,1}\),而 \(sum_{r,1}-sum_{l-1,0}\) 很明显是定值,那么只需要求最大的 \(sum_{i,0}-sum_{i-1,1}\) 即可,可用 ST 表维护,时间复杂度为 \(O(n\log n)\).

因此总时间复杂度为 \(O(n \log n+m)\),足以通过本题。

#include <cstdio>
#include <iostream>
//#include<bits/stdc++.h>

using namespace std;

namespace IO{//by cyffff
	int len=0;
	char ibuf[(1<<20)+1],*iS,*iT,out[(1<<26)+1];
	#define gh() (iS==iT?iT=(iS=ibuf)+fread(ibuf,1,(1<<20)+1,stdin),(iS==iT?EOF:*iS++):*iS++)
	#define reg register
	inline int read(){
		reg char ch=gh();
		reg int x=0;
		reg char t=0;
		while(ch<'0'||ch>'9')   t|=ch=='-',ch=gh();
		while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();
		return t?-x:x;
	}
	inline void putc(char ch){
		out[len++]=ch;
	}
	template<class T>
	inline void write(T x){
		if(x<0)putc('-'),x=-x;
		if(x>9)write(x/10);
		out[len++]=x%10+48;
	}
	inline void flush(){
		fwrite(out,1,len,stdout);
		len=0;
	}
}
using IO::read;
using IO::write;
using IO::flush;
using IO::putc;

const int N=1e6;
const int M=5e6;
const int Log=20;

int n,m;
int sum[N+5][2];
int sum2[N+5];
int f[N+5][Log];
int log[N+5];

void init() {
	log[0]=log[1]=0;
	for(int i=2;i<=n;i++) log[i]=log[i>>1]+1;
}

int query(int l,int r) {
	int s=log[r-l+1];
	return max(f[l][s],f[r-(1<<s)+1][s]);
}

int main() {
	n=read();m=read();
	init();
	int lst=-1,a;
	for(int i=1;i<=n;i++) {
		a=read();
		sum[i][0]=sum[i-1][0];
		sum[i][1]=sum[i-1][1];
		sum[i][a]++;
		sum2[i]=sum2[i-1]+(lst==0&&a==1);
		lst=a;
	}
	for(int i=1;i<=n;i++) f[i][0]=sum[i][0]-sum[i-1][1];
	for(int j=1;j<=Log;j++) {
		for(int i=1;i+(1<<j)-1<=n;i++) {
			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
		}
	}
	int op,l,r;
	while(m--) {
		op=read();l=read();r=read();
		int ans=0;
		if(op==1) {
			ans=max(1,sum[r][1]-sum[l-1][0]+query(l,r));
			write(ans);putc('\n');
		} else {
			int x;
			if(sum2[l]==sum2[r]) x=1;
			else x=2;
			write(x);putc('\n');
		}
	}
	flush();
	return 0;
}

标签:01,log,R2,int,题解,sum,IO,using
From: https://www.cnblogs.com/Scorilon/p/17666149.html

相关文章

  • CF1833D Flipper 题解
    赛场上思路出来了但是代码没调出来。首先考虑右端点,很明显,要让操作后的序列字典序尽量地大,那么就要使操作后的序列第一个数尽量地大,考虑\(n\)或\(n-1\),如果\(n\)在原序列的第一个位置,那么此时无论怎么调整都无法使得它在新序列的第一个位置,此时就要考虑让\(n-1\)在新序列......
  • UVA10054 The Necklace题解
    题意给定一个无向图,其中至多有\(50\)个结点,求是否有欧拉回路。题解很明显就是一个无向图求欧拉回路的板子,我们用\(\tt{Hierholzer}\),先说存图,要明确的一个点是这个无向图里是有可能有重边的,所以我们要注意记录的时候不应是单独地记录某一条边是否存在,而是要记录某一条边的数......
  • Facebook - 01
    main.pyfromdataimportmock_datafromcmd.show_namesimportshow_listimportosdefprint_useage():print("\t\t---------欢迎使用Facebook系统,具体命令如下:-------")print("list:显示名单")print("886:再见")print("......
  • UVA967的题解
    设\(check_i\)为\(1\simn\)中满足题意的数的数量。显然答案为\(check_j-check_{i-1}\)。注意到\(check\)能直接暴力求出来。那么就可以先把\(10^6\)范围内的所有质数求出来,然后所有数跑一遍,每个数都去旋转得出所有数后判断是否均为质数,记录下来。代码很好写。#incl......
  • 01-网页布局
    HTML语法:HTML是标记语言,用于结构化网页内容。以下是HTML的基本语法:<!DOCTYPEhtml><html><head><title>页面标题</title></head><body><h1>这是一个标题</h1><p>这是一个段落</p></body></html>排......
  • 一些奇怪的题的题解
    给定\(n\),求:\[\sum_{i=1}^n\sum_{j=1}^n\frac{i+j}{\gcd(i,j)}\]思路分析:先化式子:\[\begin{aligned}\sum_{i=1}^n\sum_{j=1}^n\frac{i+j}{\gcd(i,j)}&=\sum_{d=1}^n\sum_{i=1}^n\sum_{j=1}^n\frac{i+j}{d}[\gcd(i,j)=d]\\&=\sum_{d=1}^n\s......
  • 深入研究消息队列01
    一、消息队列技术趋势 早年业界消息队列演进的主要推动力在于功能(如延迟消息、事务消息、顺序消息等)、场景(实时场景、大数据场景等)、分布式集群的支持等等。近几年,随着云原生架构和Serverless的普及,业界MQ主要向实时消息和流消息的融合架构、Serverless、Event、协议兼容等方......
  • C-小美的01串翻转_牛客周赛 Round 9
    链接:https://ac.nowcoder.com/acm/contest/63869/C来源:牛客网题目描述小美定义一个01串的权值为:每次操作选择一位取反,使得相邻字符都不相等的最小操作次数。例如,"10001"的权值是1,因为只需要修改一次:对第三个字符取反即可。现在小美拿到了一个01......
  • CF1774 题解
    A考虑在所有\(0\)前添加正号,在\(1\)前轮流添加正负号即可。B首先根据抽屉原理,我们可以取出最多的颜色,个数记为\(mx\),然后其余颜色可以填在\(mx\)的两两中间,最少要有\((mx-1)(k-1)\)个空位。但是只是必要的,而不是充分的。考虑有多个最大值的情况,发现这些不是作为分界......
  • BUUCTF [极客大挑战 2019]HardSQL
    判断过滤哪些关键词和字符报错注入报错注入在没法用union联合查询时用,但前提还是不能过滤一些关键的函数。报错注入就是利用了数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。这里主要记录一下xpath语法错误和concat+rand()+group_by()导致主键重复xpa......