NOIP模拟赛 T3区间

news/2024/11/29 3:53:25/

题目大意

n n n个数字,第 i i i个数字为 a i a_i ai。有 m m m次询问,每次给出 k i k_i ki个区间,每个区间表示第 l i , j l_{i,j} li,j到第 r i , j r_{i,j} ri,j个数字,求这些区间中一共出现了多少种不同的数字。部分数据强制在线。

时限1s,空间8MB。

输入格式

第一行包括三个整数 n , m , p n,m,p n,m,p p p p 0 0 0 1 1 1表示是否强制在线。

第二行 n n n个正整数,第 i i i个表示 a i a_i ai

接下来依次给出每个询问,每个询问第一行一个正整数,表示 k i k_i ki。接下来 k i k_i ki行,每行两个正整数,分别表示 l i , j l_{i,j} li,j r i , j r_{i,j} ri,j

p = 1 p=1 p=1且这不是第一个询问,则输入的 l i , j l_{i,j} li,j r i , j r_{i,j} ri,j是经过加密的,你需要将这两个数字分别异或上上一个询问的答案,对 n n n取模后再加 1 1 1,两者的较小值为真实的 l i , j l_{i,j} li,j,较大值为真实的 r i , j r_{i,j} ri,j

输出格式

对每个询问输出一行一个整数表示答案。

输入样例

3 2 0
1 2 1
1
1 2
2
1 1
3 3

输出样例

2
1

数据范围

1 ≤ n , m , ∑ k i , a i ≤ 1 0 5 , 1 ≤ l i , j ≤ r i , j ≤ n 1\leq n,m,\sum k_i,a_i\leq 10^5,1\leq l_{i,j}\leq r_{i,j}\leq n 1n,m,ki,ai105,1li,jri,jn


题解

首先,我们考虑 p = 0 p=0 p=0的情况。

我们可以用 b i t s e t bitset bitset来维护每个点是否出现。先把各个区间离线下来,用莫队求出每个区间的 b i t s e t bitset bitset。把每个询问并起来。这样做的时间复杂度为 O ( n n + n m 64 ) O(n\sqrt n+\dfrac{nm}{64}) O(nn +64nm)

空间开不下,我们考虑优化。

既然要用 b i t s e t bitset bitset,那么时间复杂度肯定是要带 n m 64 \dfrac{nm}{64} 64nm的了。我们不妨将每 n 64 \dfrac{n}{64} 64n个元素分一块,对于每次询问,非整块的暴力处理,再预处理整块到整块的 b i t s e t bitset bitset即可。

空间开不下,就对这 64 64 64个块建 S T ST ST表。建 S T ST ST表不用倍增,对每种长度从左到右推一遍即可。

在优化一下常数。只出现过一次的权值,把它们单独求一个前缀和,每次特殊处理即可。这样的话,每个权值至少出现两次,离散化之后权值个数能减少至少一半。

离散化的时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn),建 S T ST ST表的时间复杂度为 O ( n log ⁡ 64 ) O(n\log 64) O(nlog64),查询的时间复杂度为 O ( n m 64 + 64 n ) O(\dfrac{nm}{64}+64n) O(64nm+64n),总时间复杂度为 O ( n m 64 ) O(\dfrac{nm}{64}) O(64nm)。因为权值个数减半,所以时间复杂度能降低到 O ( n m 128 ) O(\dfrac{nm}{128}) O(128nm)

空间复杂度为 O ( n log ⁡ 64 ) O(n\log 64) O(nlog64)

这道题有一定的思维难度,可以结合代码帮助理解。

code

#include<bits/stdc++.h>
#define N 100032
#define K 1563
#define Z 782
using namespace std;
int n,m,p,c1=0,lst,ans,a[N+5],s[1<<16],t[105],c[N+5],sum[N+5];
struct pt{unsigned long long z[Z];void set(int x){z[x>>6]|=1ull<<(x&63);}void rev(int x){z[x>>6]^=1ull<<(x&63);}int count(){int re=0;for(int i=0;i<Z;i++){re+=s[z[i]>>48]+s[(z[i]>>32)&65535]+s[(z[i]>>16)&65535]+s[z[i]&65535];}return re;}
}v,b[6][70];//按颜色分成64块
struct node{int l,r;
}w[N+5];
bool cmp(node ax,node bx){if(ax.l!=bx.l) return ax.l<bx.l;return ax.r<bx.r;
}
void kuai(int l,int r){if(l>r) return;int x=t[r-l+1];for(int i=0;i<Z;i++){v.z[i]|=b[x][l].z[i]|b[x][r-(1<<x)+1].z[i];}
}//所有大块处理
void dd(int l,int r){if((l-1)/K==(r-1)/K){for(int i=l;i<=r;i++) v.set(a[i]);}else{for(int i=l;i<=(l-1)/K*K+K;i++) v.set(a[i]);kuai((l-1)/K+1,(r-1)/K-1);for(int i=(r-1)/K*K+1;i<=r;i++) v.set(a[i]);}
}//分块
int main()
{scanf("%d%d%d",&n,&m,&p);for(int i=2;i<=64;i++) t[i]=t[i>>1]+1;for(int i=1;i<1<<16;i++) s[i]=s[i>>1]+(i&1);for(int i=1;i<=n;i++){scanf("%d",&a[i]);++c[a[i]];}for(int i=1;i<=n;i++){sum[i]=sum[i-1];if(c[a[i]]==1){a[i]=0;++sum[i];}}//若只出现过一次,放到前缀和数组中for(int i=1;i<=n;i++){if(a[i]) c[++c1]=a[i];}sort(c+1,c+c1+1);c1=unique(c+1,c+c1+1)-c-1;for(int i=1;i<=n;i++){if(a[i]){a[i]=lower_bound(c+1,c+c1+1,a[i])-c;}}//离散化for(int i=0,x=K;i<6;i++,x<<=1){memset(v.z,0,sizeof(v.z));memset(c,0,sizeof(c));for(int j=1;j<=x;j++){if(!c[a[j]]) v.rev(a[j]);++c[a[j]];}b[i][0]=v;for(int j=K;j+x<=N;j+=K){for(int k=0;k<K;k++){if(!c[a[j+x-k]]) v.rev(a[j+x-k]);++c[a[j+x-k]];--c[a[j-k]];if(!c[a[j-k]]) v.rev(a[j-k]);}b[i][j/K]=v;}//按位置分成64块}//ST表for(int o=1,k,l,r;o<=m;o++){ans=0;memset(v.z,0,sizeof(v.z));scanf("%d",&k);for(int i=1;i<=k;i++){scanf("%d%d",&w[i].l,&w[i].r);if(p&&o>1){w[i].l=(w[i].l^lst)%n+1;w[i].r=(w[i].r^lst)%n+1;if(w[i].l>w[i].r) swap(w[i].l,w[i].r);}}sort(w+1,w+k+1,cmp);l=w[1].l;r=w[1].r;for(int i=2;i<=k;i++){if(w[i].l>r+1){ans+=sum[r]-sum[l-1];dd(l,r);l=w[i].l;}r=max(r,w[i].r);}ans+=sum[r]-sum[l-1];dd(l,r);//合并区间ans+=v.count()-(v.z[0]&1);//z[0]的第一个位置是为0的a值,不统计lst=ans;printf("%d\n",ans);//求答案}return 0;
}

http://www.ppmy.cn/news/46260.html

相关文章

用Abp实现找回密码和密码强制过期策略

文章目录 重置密码找回密码发送验证码校验验证码发送重置密码链接创建接口 密码强制过期策略改写接口 Vue网页端开发重置密码页面忘记密码控件密码过期提示 项目地址 用户找回密码&#xff0c;确切地说是 重置密码&#xff0c;为了保证用户账号安全&#xff0c;原始密码将不再…

【通过Cpython3.9源码看看列表到底是咋回事】

列表结构 typedef struct {PyObject_VAR_HEAD/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */PyObject **ob_item;/* ob_item contains space for allocated elements. The number* currently in use is ob_size.* Invariants:* 0 < ob_siz…

ObjectARX中的坐标系以及坐标转换

1 AutoCAD中的坐标系种类 WCS World Coordinate System. The “reference” coordinate system. All other coordinate systems are defined relative to the WCS, which never changes. Values measured relative to the WCS are stable across changes to other coordinate s…

MySQL数据库——MySQL数据类型的选择

MySQL 提供了大量的数据类型&#xff0c;为了优化存储和提高数据库性能&#xff0c;在任何情况下都应该使用最精确的数据类型。 前面主要对 MySQL 中的数据类型及其基本特性进行了描述&#xff0c;包括它们能够存放的值的类型和占用空间等。本节主要讨论创建数据库表时如何选择…

Hive常用命令

1.hive模糊搜索表 show tables like *name*; ANALYZE TABLE tablename [PARTITION(partcol1[val1], partcol2[val2], ...)] COMPUTE STATISTICS [noscan]; 2.查看表结构信息 desc formatted table_name;desc table_name; 3.查看分区信息 show partitions table_name; 4.根…

重要公告 | 首批Moonbeam Accelerator孵化项目官宣

通过Moonbeam Accelerator计划&#xff0c;Arrington Capital和Borderless Capital将Moonbeam作为跨链创新的首选目的地 跨链互连应用的最佳去中心化开发平台Moonbeam很高兴宣布&#xff1a;在Rokk3r的运营之下&#xff0c;入选Moonbeam Accelerator计划的Web3初创公司首次亮相…

ArcGIS制作建设项目使用林地现状图

近年来&#xff0c;随着经济社会的快速发展&#xff0c;各地建设项目不断增多&#xff0c;占用征用林地项目的数量也呈逐年上升的趋势。根据《占用征用林地审核审批管理规范》规定&#xff0c;建设项目申请占用征用林地&#xff0c;应编制的项目使用林地可行性报告&#xff1b;…

【linux】 安装 java 环境

目录 1.检查linux 下是否安装java(jdk)环境2.查看 linux 的操作系统版本3.下载jdk4.新建java文件夹用于安装jdk5.将下载到本地的jdk压缩包上传到linux服务器6.配置环境变量 1.检查linux 下是否安装java(jdk)环境 可通过下面五条命令来查看linux 系统是否安装了java 环境 1、jav…