当前位置: 首页 > news >正文

NOIP模拟赛 T3区间

题目大意

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.lryc.cn/news/61240.html

相关文章:

  • 【Python】如何用pyth做游戏脚本(太简单了吧)
  • 【Linux】磁盘与文件系统
  • Transformer中的注意力机制及代码
  • ChatGPT在连续追问下对多线程和双重检查锁模式的理解--已经超越中级程序员
  • 每天一道大厂SQL题【Day22】华泰证券真题实战(四)
  • 【智能电网】智能电网中针对DOS和FDIA的弹性分布式EMA(Matlab代码实现)
  • IDEA 创建微服务项目实例
  • 注册苹果开发者账号的方法
  • OpenCV2 计算机视觉应用编程秘籍:1~5
  • Domino自带的JSON校验工具
  • CentOS(linux)使用Docker安装nacos
  • 无线测温在线监测系统工作原理与产品选型
  • Nginx rewrite ——重写跳转
  • 【华为OD机试真题 C++】1038 - 全量和已占用字符集 | 机试题+算法思路+考点+代码解析
  • 网络中的网关和物联网的网关区别 局域网 路由器 交换机 服务器
  • 2023 年嵌入式世界的3 大趋势分析
  • 基于 DolphinDB 机器学习的出租车行程时间预测
  • Python调用最小二乘法
  • 15.数据表格.上
  • 在poetry虚拟环境下打包exe
  • 【Unity VR开发】结合VRTK4.0:高亮与标签
  • 有了MySQL,为什么还要有NoSQL
  • 找PPT模板就上这5个网站~
  • Ae:摄像机选项
  • 嵌入式日志库ulog的使用和解析
  • 自阿里P8爆出内部1031道java面试题后,在Boss直聘狂拿千份Offer
  • Java最新面试题100道,包含答案示例(41-50题)
  • C++之深入解析野指针和悬空指针
  • YOLOv7+单目测距(python)
  • SYSU程设c++(第九周)函数对象、友元函数、友元类