Description

Link.

无修支持查询:查询一个区间 \([l,r]\) 中所有子序列分别去重后的和 \(\bmod\ p\)

Solution

这是数据结构一百题的第50题(一半了哦)的纪念题解。

无修改操作,基本确定大方向莫队。

考虑查询的问题,我们可以转化一下。即求区间内每个数出现的次数。

一个区间 \([l,r]\) 的子序列数量为:

\[\sum_{i=0}^{r-l+1}C^{i}_{r-l+1}=2^{r-l+1}
\]

比如一个数在区间 \([l,r]\) 出现了 \(k\) 次,那么一共有 \(2^{r-l+1-k}\) 个子序列不包含这个数。这个很好理解,从组合数的意义可知。那么就有 \(2^{r-l+1}-2^{r-l+1-k}\) 个子序列包含了这个数。

那么我们就可以用莫队维护区间中出现了 \(k\) 次的所有数的和,然后乘上一个 \(2^{r-l+1}-2^{r-l+1-k}\) 就是它的贡献了。

问题又来了:每次询问的模数是不确定的,我们需要每次都需要 \(\Theta(n)\) 处理一遍2的幂。

有没有什么方法能把处理这个东西的复杂度降到 \(\Theta(\sqrt{n})\) 或以下呢?

对此SyadouHayami表示我们可以打个高精。

方法是有的。

我们可以每次询问都处理出 \(2^{1},2^{2},\cdots,2^{\sqrt{n}}\) ,以及 \(2^{2\sqrt{n}},2^{3\sqrt{n}},\cdots,2^{n}\),都只需要 \(\Theta(\sqrt{n})\)。当然,都是在模 \(p\) 的意义下的。我们分别记为pow1pow2

那么 \(2^{x}\operatorname{mod}p=(pow1_{x\operatorname{mod}\sqrt{n}}\times pow2_{\lfloor x\div\sqrt{n}\rfloor})\operatorname{mod}p\)。

于是就解决问题了。

我的代码遇到了一下两个玄学问题,贴出来给同样情况的人看看:

  1. 链表部分的prevnext如果放在结构体里会T。

  2. pow1,pow2,sum,cnt几个数组的定义如果放在最开头和isa以及ans两个数组一起会RE。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue> using namespace std; const int Maxn = 1e5 + 10;
const int Size = 320;
int n, m, isa[ Maxn ], ans[ Maxn ];
struct Query_Node
{
int l, r, p, id, pos;
} Q[ Maxn ];
struct Linked_List
{
int tot, prev[ Maxn ], next[ Maxn ];
Linked_List( ) { tot = 0; } void insert( int x )
{
next[ tot ] = x;
prev[ x ] = tot;
tot = x;
} void erase( int x )
{
if( tot == x ) tot = prev[ x ];
else
{
next[ prev[ x ] ] = next[ x ];
prev[ next[ x ] ] = prev[ x ];
}
prev[ x ] = next[ x ] = 0;
}
} llt; bool cmp( Query_Node rhs, Query_Node shr )
{
if( rhs.pos != shr.pos ) return rhs.l < shr.l;
else return rhs.r < shr.r;
} int pow1[ Maxn ], pow2[ Maxn ];
void Pare_Two( int p )
{
pow1[ 0 ] = pow2[ 0 ] = 1;
for( int i = 1; i <= Size; ++ i ) pow1[ i ] = 1ll * 2 * pow1[ i - 1 ] % p;
for( int i = 1; i <= Size; ++ i ) pow2[ i ] = 1ll * pow1[ Size ] * pow2[ i - 1 ] % p;
} int Get_Two( int x, int p )
{
return 1ll * pow1[ x % Size ] * pow2[ x / Size ] % p;
} int sum[ Maxn ], cnt[ Maxn ];
void Make_Cont( int x, int f )
{
int pos = isa[ x ];
sum[ cnt[ pos ] ] -= pos;
if ( ! sum[ cnt[ pos ] ] ) llt.erase( cnt[ pos ] );
if( f == 1 ) ++cnt[ pos ];
else --cnt[ pos ];
if ( ! sum[ cnt[ pos ] ] ) llt.insert( cnt[ pos ] );
sum[ cnt[ pos ] ] += pos;
} void Contribute( )
{
int l = 1, r = 0;
for( int i = 1; i <= m; ++ i )
{
Pare_Two( Q[ i ].p );
while( l > Q[ i ].l ) Make_Cont( --l, 1 );
while( l < Q[ i ].l ) Make_Cont( l++, 0 );
while( r > Q[ i ].r ) Make_Cont( r--, 0 );
while( r < Q[ i ].r ) Make_Cont( ++r, 1 );
for( int s = llt.next[ 0 ]; s; s = llt.next[ s ] )
{
int val = 1ll * sum[ s ] * ( Get_Two( r - l + 1, Q[ i ].p ) - Get_Two( r - l + 1 - s, Q[ i ].p ) + Q[ i ].p ) % Q[ i ].p;
ans[ Q[ i ].id ] += val;
ans[ Q[ i ].id ] %= Q[ i ].p;
}
}
} signed main( )
{
scanf( "%d %d", &n, &m );
for( int i = 1; i <= n; ++ i ) scanf( "%d", &isa[ i ] );
for( int i = 1; i <= m; ++ i )
{
int l, r, p;
scanf( "%d %d %d", &l, &r, &p );
Q[ i ].l = l, Q[ i ].r = r;
Q[ i ].p = p, Q[ i ].id = i;
Q[ i ].pos = l / Size;
}
sort( Q + 1, Q + 1 + m, cmp );
Contribute( );
for( int i = 1; i <= m; ++ i )
printf( "%d\n", ans[ i ] );
return 0;
}

Solution -「洛谷 P5072」「YunoOI 2015」盼君勿忘的更多相关文章

  1. 洛谷:P5072 [Ynoi2015]盼君勿忘

    原题地址:https://www.luogu.org/problem/P5072 题目简述 给定一个序列,每次查询一个区间[l,r]中所有子序列分别去重后的和mod p 思路 我们考虑每个数的贡献.即 ...

  2. 洛谷P5072 [Ynoi2015]盼君勿忘 [莫队]

    传送门 辣鸡卡常题目浪费我一下午-- 思路 显然是一道莫队. 假设区间长度为\(len\),\(x\)的出现次数为\(k\),那么\(x\)的贡献就是\(x(2^{len-k}(2^k-1))\),即 ...

  3. 【洛谷5072】[Ynoi2015] 盼君勿忘(莫队)

    点此看题面 大致题意: 一个序列,每次询问一个区间\([l,r]\)并给出一个模数\(p\),求模\(p\)意义下区间\([l,r]\)内所有子序列去重后值的和. 题意转化 原来的题意看起来似乎很棘手 ...

  4. 【题解】Luogu P5072 [Ynoi2015]盼君勿忘

    众所周知lxl是个毒瘤,Ynoi道道都是神仙题,题面好评 原题传送门 一看这题没有修改操作就知道这是莫队题 我博客里对莫队的简单介绍 既然是莫队,我们就要考虑每多一个数或少一个数对答案的贡献是什么 假 ...

  5. P5072 [Ynoi2015]盼君勿忘

    传送门 一开始理解错题意了--还以为是两个子序列相同的话只算一次--结果是子序列里相同的元素只算一次-- 对于一个区间\([l,r]\),设其中\(x\)出现了\(k\)次,那么它的贡献就是它的权值乘 ...

  6. Luogu P5072 [Ynoi2015]盼君勿忘

    题意 给定一个长度为 \(n\) 的序列 \(a\) 和 \(m\) 次询问,第 \(i\) 次询问需要求出 \([l_i,r_i]\) 内所有子序列去重之后的和,对 \(p_i\) 取模. \(\t ...

  7. 题解 P5072 【[Ynoi2015] 盼君勿忘】

    在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐渐消逝的未来.我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘 ...

  8. 「区间DP」「洛谷P1043」数字游戏

    「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...

  9. 「 洛谷 」P2768 珍珠项链

    珍珠项链 题目限制 内存限制:125.00MB 时间限制:1.00s 标准输入输出 题目知识点 动态规划 \(dp\) 矩阵 矩阵乘法 矩阵加速 矩阵快速幂 题目来源 「 洛谷 」P2768 珍珠项链 ...

  10. 「 洛谷 」P4539 [SCOI2006]zh_tree

    小兔的话 推荐 小兔的CSDN [SCOI2006]zh_tree 题目限制 内存限制:250.00MB 时间限制:1.00s 标准输入输出 题目知识点 思维 动态规划 \(dp\) 区间\(dp\) ...

随机推荐

  1. C++面试八股文:C和C++有哪些区别?

    某日小二参加XXX科技公司的C++高级工程师开发岗位1面: 面试官:请问C和C++的区别有哪些? 小二:C++是C的超集. 面试官:还有吗? 小二:... 面试官:面试结束,回去等消息吧. 小二:淦. ...

  2. Python 安装教程,新手入门(超详细)含Pycharm开发环境安装教程

    目录 一.Python介绍 二.Python安装教程 (一)Python的下载 (二)Python的安装 三.Pycharm开发工具的安装 (一)Pycharm介绍 (二)Pycharm的下载 (三) ...

  3. 【技术积累】Java中的JVM【一】

    什么是JVM JVM英文全称为Java Virtual Machine,中文意为Java虚拟机.JVM是一种能够执行Java语言编写的程序的虚拟机器,它首次作为Java语言的一部分,后来又被移植到了许 ...

  4. CKS 考试题整理 (07)-RBAC - RoleBinding

    Context 绑定到 Pod 的 ServiceAccount 的 Role 授予过度宽松的权限,完成以下项目以减少权限集. Task 一个名为 web-pod 的现有 Pod 已在 namespa ...

  5. 3. Servlet原理

    Servlet 是 Java Web 应用程序中的重要组件之一,它是一个 Java 类,用于处理客户端 HTTP 请求和生成 HTTP 响应.Servlet 的原理如下: 服务器启动时,Servlet ...

  6. 【神经网络】基于GAN的生成对抗网络

    目录 [神经网络]基于GAN的生成对抗网络 随着深度学习的快速发展,神经网络逐渐成为人工智能领域的热点话题.神经网络是一种模仿人脑计算方式的算法,其通过大量数据和复杂的计算模型,能够实现复杂的任务和预 ...

  7. 2023-06-25:redis中什么是缓存穿透?该如何解决?

    2023-06-25:redis中什么是缓存穿透?该如何解决? 答案2023-06-25: 缓存穿透 缓存穿透指的是查询一个根本不存在的数据,在这种情况下,无论是缓存层还是存储层都无法命中.因此,每次 ...

  8. 一文掌握设计模式(定义+UML类图+应用)

    一.引子 从学编程一开始就被告知,要想做一名优秀的程序员两大必要技能:1.源码阅读(JDK.C等底层语言封装) 2.设计模式(使用某种语言优雅的落地典型场景功能).一般随着工作年限的增长,被迫对底层语 ...

  9. 2021级HAUT新生周赛题解汇总

    2021级HAUT新生周赛(一)题解@张君毅:第一场 2021级HAUT新生周赛(二)题解@李亚凯:第二场 2021级HAUT新生周赛(三)题解@李晨曦:第三场 2021级HAUT新生周赛(四)题解@ ...

  10. pycharm链接mysql报错: Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.

    检查驱动 我本机安装的mysql版本是5.6的,那么IDEA要连接mysql也应该匹配下驱动版本.把Driver改成MySQL for 5.1就可以了. 参考链接:https://blog.csdn. ...