bzoj3809:Gty的二逼妹子序列

2023-12-19 03:40
文章标签 序列 妹子 bzoj3809 gty

本文主要是介绍bzoj3809:Gty的二逼妹子序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【题目描述】

Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。

 

对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。

 

为了方便,我们规定妹子们的美丽度全都在[1,n]中。

 

给定一个长度为n(1≤n≤100000)的正整数序列s(1≤si≤n),对于m(1≤m≤1000000)次询问“l,r,a,b”,每次输出sl...sr中,权值∈[a,b]的权值的种类数。

 

【输入】

第一行包括两个整数n,m(1≤n≤100000,1≤m≤1000000),表示数列s中的元素数和询问数。

 

第二行包括n个整数s1...sn(1≤si≤n)。

 

接下来m行,每行包括4个整数l,r,a,b(1≤l≤r≤n,1≤a≤b≤n),意义见题目描述。

 

保证涉及的所有数在C++的int内。

 

保证输入合法。

 

【输出】

对每个询问,单独输出一行,表示sl...sr中权值∈[a,b]的权值的种类数。

 

【输入样例】

10 10
4 4 5 1 4 1 5 1 2 1
5 9 1 2
3 4 7 9
4 4 2 5
2 3 4 7
5 10 4 4
3 9 1 1
1 4 5 9
8 9 3 3
2 2 1 6
8 9 1 4

【输出样例】

2
0
0
2
1
1
1
0
1
2

【提示】

v>样例的部分解释:

 

5 9 1 2

子序列为4 1 5 1 2

在[1,2]里的权值有1,1,2,有2种,因此答案为2。

 

3 4 7 9

子序列为5 1

在[7,9]里的权值有5,有1种,因此答案为1。

 

4 4 2 5

子序列为1

没有权值在[2,5]中的,因此答案为0。

 

2 3 4 7

子序列为4 5

权值在[4,7]中的有4,5,因此答案为2。

 

建议使用输入/输出优化。

 

题解:

莫队,将询问以左端点所处块的位置为第一关键字,右端点位置为第二关键字排序,保证对于左端点在同一块内的所有询问,其右端点单增

然后对权值分块,即可O(1)修改,O(sqrt(n))查询

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
struct qz{int l,r,al,br,num;
}q[1000005];
int n,m,sz;
int arr[MAXN],idx[MAXN],blo[320],cnt[MAXN],ans[1000005];
inline int read()
{int X=0,w=0; char ch=0;while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X;
}
inline void write(int x)
{if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0');
}
inline bool cmp(qz a1,qz b1)
{if(idx[a1.l]<idx[b1.l])return true;if(idx[a1.l]==idx[b1.l])if(a1.r<b1.r)return true;return false;       
}
inline int query(int ll,int rr)
{int ret=0;if(idx[ll]==idx[rr]){for(register int i=ll;i<=rr;i++)if(cnt[i]!=0)ret++;return ret;       }if(ll==(idx[ll]-1)*sz+1&&rr==idx[rr]*sz){for(register int i=idx[ll];i<=idx[rr];i++)ret+=blo[i];return ret;    }      int lx=idx[ll]*sz,rx=(idx[rr]-1)*sz+1;for(register int i=ll;i<=lx;i++)if(cnt[i]!=0)ret++;for(register int i=rx;i<=rr;i++)if(cnt[i]!=0)ret++;lx=idx[ll]+1;rx=idx[rr]-1;       for(register int i=lx;i<=rx;i++)ret+=blo[i];return ret;            
}
inline void del(int p)
{cnt[p]--;if(cnt[p]==0)blo[idx[p]]--;
}
inline void add(int p)
{cnt[p]++;if(cnt[p]==1)blo[idx[p]]++;
}
int main()
{n=read();m=read();sz=(int)sqrt(n);for(register int i=1;i<=n;i++)idx[i]=(i-1)/sz+1;for(register int i=1;i<=n;i++)arr[i]=read();for(register int i=1;i<=m;i++){q[i].num=i;q[i].l=read();q[i].r=read();q[i].al=read();q[i].br=read();}sort(q+1,q+1+m,cmp);int L=1,R=0;for(register int i=1;i<=m;i++){while(L<q[i].l){del(arr[L]);L++;}while(R>q[i].r){del(arr[R]);R--;}                  while(L>q[i].l){L--;add(arr[L]);}while(R<q[i].r){R++;add(arr[R]);}  ans[q[i].num]=query(q[i].al,q[i].br);                             }for(register int i=1;i<=m;i++){write(ans[i]);printf("\n");}return 0;
}
View Code

 

转载于:https://www.cnblogs.com/nanjolno/p/9348413.html

这篇关于bzoj3809:Gty的二逼妹子序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/510779

相关文章

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

day-50 求出最长好子序列 I

思路 二维dp,dp[i][h]表示nums[i] 结尾,且有不超过 h 个下标满足条件的最长好子序列的长度(0<=h<=k),二维数组dp初始值全为1 解题过程 状态转换方程: 1.nums[i]==nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h]+1) 2.nums[i]!=nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h-1

LeetCode:3177. 求出最长好子序列 II 哈希表+动态规划实现n*k时间复杂度

3177. 求出最长好子序列 II 题目链接 题目描述 给你一个整数数组 nums 和一个非负整数k 。如果一个整数序列 seq 满足在下标范围 [0, seq.length - 2] 中 最多只有 k 个下标i满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为好序列。请你返回 nums中好子序列的最长长度。 实例1: 输入:nums = [1,2,1,1,3],

用Python实现时间序列模型实战——Day 14: 向量自回归模型 (VAR) 与向量误差修正模型 (VECM)

一、学习内容 1. 向量自回归模型 (VAR) 的基本概念与应用 向量自回归模型 (VAR) 是多元时间序列分析中的一种模型,用于捕捉多个变量之间的相互依赖关系。与单变量自回归模型不同,VAR 模型将多个时间序列作为向量输入,同时对这些变量进行回归分析。 VAR 模型的一般形式为: 其中: ​ 是时间  的变量向量。 是常数向量。​ 是每个时间滞后的回归系数矩阵。​ 是误差项向量,假

时间序列|change point detection

change point detection 被称为变点检测,其基本定义是在一个序列或过程中,当某个统计特性(分布类型、分布参数)在某时间点受系统性因素而非偶然因素影响发生变化,我们就称该时间点为变点。变点识别即利用统计量或统计方法或机器学习方法将该变点位置估计出来。 Change Point Detection的类型 online 指连续观察某一随机过程,监测到变点时停止检验,不运用到

Leetcode面试经典150题-128.最长连续序列-递归版本另解

之前写过一篇这个题的,但是可能代码比较复杂,这回来个简洁版的,这个是递归版本 可以看看之前的版本,两个版本面试用哪个都保过 解法都在代码里,不懂就留言或者私信 class Solution {/**对于之前的解法,我现在提供一共更优的解,但是这种可能会比较难懂一些(思想方面)代码其实是很简洁的,总体思想如下:不需要排序直接把所有数放入map,map的key是当前数字,value是当前数开始的

go json反序列化成指定类型

简介 简单的介绍一下使用go的json库,将json字符串反序列化成接口中指定的实现类 代码如下 package usejsontype ExamInterface interface {CheckRule(data any) bool}type IntStru struct {DefalutVal int `json:"defalut_val"`Max int `json:

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II 1.题目 1.1递增子序列 题目链接:491. 非递减子序列 - 力扣(LeetCode) 视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列_哔哩哔哩_bilibili 文档讲解:https://programmercarl.com/0491.%E9%80%92%E