首页 > 其他分享 >20241120 校内模拟赛 T3 题解

20241120 校内模拟赛 T3 题解

时间:2024-11-20 09:45:01浏览次数:1  
标签:10 20241120 题解 样例 T3 long int 哈希 区间

题目描述

给定一个数列 \(A\),数列的元素取值范围为 \([1,m]\)。

请计算有多少个非空子区间满足以下条件:该区间内每个元素的出现次数都相同(没有出现的元素视为出现 \(0\) 次)。

例如,当 \(m=3\) 时,\([1,2,3]\) 和 \([1,1,3,2,3,2]\) 是满足条件的区间,而 \([1,2,2,3]\) 和 \([1,1,3,3]\) 不满足条件。

请计算数列 \(A\) 的满足条件的非空子区间数量。

输入格式

包含多组测试数据,第一行一个正整数 \(T\) 代表数据组数。

每组数据两行,第一行两个整数 \(n,m\),代表序列长度和元素值域。

第二行 \(n\) 个整数,代表该序列,保证序列中的元素在 \([1,m]\) 之间。

输出格式

\(T\) 行,每行一个整数,代表对应组数数据的序列的满足条件的非空子区间个数。

样例

样例输入 1

1
6 3
1 2 3 1 2 3

样例输出 1

5

样例解释 1

有 \([1,3],[2,4],[3,5],[4,6],[1,6]\) 共 \(55\) 个。

样例输入 2

1
10 4
1 1 2 4 3 2 4 3 2 1

样例输出 2

3

样例解释 2

有 \([2,5],[1,8],[7,10]\) 共 \(33\) 个。

数据范围与提示

对于 \(100%\) 的数据, \(1≤T≤5,1≤n≤106,1≤m≤n\)。

测试点 \(n\) \(m\)
\(1\) \(≤50\) \(≤50\)
\(2\) \(≤300\) \(≤300\)
\(3\) \(≤3000\) \(≤3000\)
\(4\) \(≤7000\) \(≤7000\)
\(5,6,7\) \(≤7 × 10^4\) \(≤300\)
\(8\) \(≤3×10^5\) \(≤3×10^5\)
\(9,10\) \(≤10^6\) \(≤10^6\)

解法说明

首先让我们考虑一下暴力的做法。记 \(f_{i,j}\) 为截至第 \(i\) 项数字 \(j\) 出现的次数,显然对于区间 \((l,r]\),当且仅当 \(\forall i,j \in [1,m],f_{r,i}-f_{l,i}=f_{r,j}-f_{l,j}\) 时,该区间合法。

接下来考虑优化。这事实上等价于对 \(f_i\) 和 \(f_j\) 求差分数组,当二者差分数组相同时,该区间合法。此时原问题转化为维护每个位置 \(f\) 的差分数组的集合,寻找匹配数。可以使用类似异或哈希的技巧,求出每个位置 \(f\) 的差分数组的哈希值,从而快速求出答案。如此复杂度已足够优秀,可以拿到满分。

但从上文的异或哈希角度出发,还能得到一个更简单的做法。用梅森旋转生成 \(m-1\) 个数,分别作为 \(A_1\) 到 \(A_{m-1}\) 的哈希值,记其和的相反数为 \(A_m\) 的哈希值。令 \(id_i\) 表示 \(i\) 的哈希值,记 \(f_i=\sum_{j=1}^i id_{A_j}\),当所有数出现次数相同时,其哈希值之和应为 \(0\)。即对于区间 \((l,r]\),当且仅当 \(f_l=f_r\) 时,该区间合法。故 \(f\) 中的相同元素的对数即为原问题的答案。

通过代码

#include<bits/stdc++.h>

#define int long long//记得开long long
#define ull unsigned long long
const int N=1e6+10;

namespace IO{
    inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return x*f; }
    inline void write(int x){ if(x>9) write(x/10); putchar(x%10+'0'); }
}using namespace IO;//快读快写

namespace code{
    int n,m,ans,id[N];
    ull a[N],sum;
    std::mt19937_64 random(time(0));//用梅森旋转算法生成高质量的伪随机数序列

    void solve(){
        n=read(),m=read(),ans=0,sum=0;//多测不清空,亲人两行泪
        for(int i=1;i<m;++i) id[i]=random(),sum+=id[i];//为第 1 到 m-1 项赋哈希值
        id[m]=-sum;//第 m 项的哈希值为前 m-1 项的哈希值的和的相反数
        for(int i=1;i<=n;++i) a[i]=a[i-1]+id[read()];//a[i] 表示第 1 到 i 项的哈希值的和
        std::sort(a,a+n+1);//排序,方便计算
        for(int i=1,cnt=1;i<=n;++i,++cnt,ans+=cnt-1) if(a[i]!=a[i-1]) cnt=0;//累加答案
        write(ans),putchar('\n');
    }
}

signed main(){
    int T=read();
    while(T--) code::solve();
    return 0;
}

标签:10,20241120,题解,样例,T3,long,int,哈希,区间
From: https://www.cnblogs.com/Alexxtl/p/18556177

相关文章

  • Luogu P9869 NOIp2023 三值逻辑 题解 [ 绿 ] [ 带权并查集 ]
    三值逻辑:有点坑并且细节较繁琐,但有点板子的并查集。修改操作发现对于每个点,只有对他的最后一次操作才是有用的,所以记录下最终的祖先即可。然而这里并不能用并查集来实现,因为并查集它具有的是传递性,无论你路不路径压缩,每次修改一个父节点时它的子节点一定会被修改,所以我们不能使......
  • CF2037E 题解
    CF2037E题解题意给定一个长度为\(n\)的\(01\)串,定义\(f(l,r)\)为\(l\)到\(r\)区间内\(01\)子序列的数量,通过最多\(n\)次交互,确定这个\(01\)串的构成。分析可以从莫队的思想,也就是增量,来思考如何解决。如果说我们已经知道了\(f(l,r)=ans\),接下来我们询问......
  • CF 1253 题解
    CF1253题解ASinglePush考虑令\(d_i=b_i-a_i\),那么合法当且仅当\(d\)在一个前缀和一个后缀都是\(0\),其余地方值一致并且非负.BSillyMistake注意到能作一次划分的时候立即划分一定更优,因为这样就不会因为潜在的一天两次进入办公室而得不到答案.贪心的模拟即可.......
  • 2024年全国职业院校技能大赛中职组《大数据应用与服务赛项》赛项赛题解析第三模块
      职业院校技能大赛大数据应用与服务交流群:q743959419目录模块三:数据分析与可视化任务一:数据分析与可视化子任务一:柱状图数据分析与可视化子任务二:折线图数据分析与可视化子任务三:饼图数据分析与可视化子任务四:雷达图数据分析与可视化任务二:数据分析子任务一:Excel......
  • Public NOIP Round #6 D 排序 题解
    Description今天是YQH的生日,她得到了一个\(1\simn\)的排列作为礼物。YQH是一个有强迫症的女孩子,她希望把这个排列从小到大排序,具体的,她可以进行这样的操作:把\([1,n]\)分成若干个区间,假如是\(m\)段,依次为\([l_1,r_1],[l_2,r_2],\dots,[l_m,r_m]\),其中\(l_1=1,r_m=......
  • 【题解】洛谷:P4805 [CCC2016] 合并饭团
    P4805[CCC2016]合并饭团希望写完这篇题解能真正地会这种题。合并两个的操作很像合并石子的操作,确实直接那么做就可以,但三个怎么办呢,暴力做法就是枚举中间两个端点然后转移,但是这样复杂度太大了有\(O(n^4)\)。于是搬出我们的双指针,在面对区间问题时双指针可以有效地解决问题,......
  • UOJ918 【UR #28】偷吃蛋糕 题解
    题目描述\(n\)层蛋糕,第\(i\)层大小\(c_i\),保证\(c_i\)单调不增。初始你有第\(1\)层蛋糕,然后重复以下操作,直至没有蛋糕:吃掉最大的一层蛋糕,记其大小为\(x\)。如果还有至少\(x\)层蛋糕没有给你,主办方会按编号升序给你接下来的\(x\)层蛋糕。如果只有\(y\)层蛋......
  • File Recovery FAT32 dominantin SD
    Lab4:FileRecoveryIntroductionFAThasbeenaroundfornearly50years.Becauseofitssimplicity,itisthemostwidelycompatiblefilesystem.Althoughrecentcomputershaveadoptednewerfilesystems,FAT32(anditsvariant,exFAT)isstilldominan......
  • C -- [vs2019] C2440 错误,无法从 const char[] 转换为 char*问题解决
    https://blog.csdn.net/weixin_45525272/article/details/118699716原因新标准中,不能把指针指向一串常量解决方案一:引入[]char*str=“helloworld”;改成:charstr_tmp[]=“helloworld”;char*str=str_tmp;方案二:加constchar*str=“helloworld”;改成:......
  • ABC380 DEFG 题解
    ABC380题解赛时秒了ABCDE(好吧其实还是略有卡顿,写完大概花了55min),看到F有博弈直接跑了,没注意到数据范围这么小,看到G一下就会了大致思路,但具体细节上搞复杂了,快写完了才发现不用维护这么多(恼),然后因为某些神秘错误现在都还没有调出来。至于F,赛后看见数据范围这么小,自己独立......