2021牛客多校1 - Hash Function(思维+FFT)

Posted Frozen_Guardian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021牛客多校1 - Hash Function(思维+FFT)相关的知识,希望对你有一定的参考价值。

题目链接:点击查看

题目大意:给出一个长度为 n n n 的序列,现在要求找到一个 s e e d seed seed,使得所有数字变为 a [ i ] = a [ i ] m o d    s e e d a[i]=a[i]\\mod seed a[i]=a[i]modseed 后两两互不相同,找到最小的 s e e d seed seed

题目分析:考虑转换模型,如果存在着 i i i j j j 使得 a [ i ] ≡ a [ j ] ( m o d s e e d ) a[i] \\equiv a[j] \\pmod {seed} a[i]a[j](modseed),那么肯定有 a [ i ] + k ∗ s e e d = a [ j ] a[i]+k*seed=a[j] a[i]+kseed=a[j],其中 k k k 为任意正整数,移项可得 a [ i ] − a [ j ] ≡ 0 ( m o d s e e d ) a[i]-a[j] \\equiv 0 \\pmod{seed} a[i]a[j]0(modseed),到此模型转换为寻找到最小的正整数 m m m,其中不是任意一对 ∣ a [ i ] − a [ j ] ∣ |a[i]-a[j]| a[i]a[j] 的约数。

直接按照项数枚举的话复杂度是 n 2 n^2 n2 级别的,观察到值域是 [ 0 , 500000 ] [0,500000] [0,500000] 的,即 a [ i ] , a [ j ] ∈ [ 0 , 500000 ] a[i],a[j] \\in[0,500000] a[i],a[j][0,500000],推得 ∣ a [ i ] − a [ j ] ∣ ∈ [ 0 , 500000 ] |a[i]-a[j]|\\in[0,500000] a[i]a[j][0,500000],因为本题中任意两项的值都互不相等,所以可以从值域入手,判断某个值是否存在,此时只需要枚举答案 s e e d seed seed,就可以在 O ( n l o g n ) O(nlogn) O(nlogn) 的时间复杂度内检查答案是否合法。

我们将 a [ i ] = x a[i]=x a[i]=x 转换为 P [ x ] = 1 P[x]=1 P[x]=1,令多项式 { P 0 , P 1 , . . . , P 500000 − 1 , P 500000 } \\{ P_{0},P_{1},...,P_{500000-1},P_{500000} \\} {P0,P1,...,P5000001,P500000} { P 0 , P − 1 , . . . , P − ( 500000 − 1 ) , P − 500000 } \\{ P_{0},P_{-1},...,P_{-(500000-1)},P_{-500000} \\} {P0,P1,...,P(5000001),P500000} 进行卷积,这样对于其中的 P [ i ] P[i] P[i] P [ j ] P[j] P[j],卷积后得到 P [ i + j ] P[i+j] P[i+j],因为 j j j (下标)是负数,所以自然得到了所有的 P i − j P_{i-j} Pij

到此为止就可以用 ntt 或 fft 进行优化了,不过多项式卷积不支持负数,所以需要给会出现负数的位置增加一个偏移量 l i m i t limit limit,令第二个多项式变为: { P l i m i t − 0 , P l i m i t − 1 , . . . , P l i m i t − ( 500000 − 1 ) , P l i m i t − 500000 } \\{ P_{limit-0},P_{limit-1},...,P_{limit-(500000-1)},P_{limit-500000} \\} {Plimit0,Plimit1,...,Plimit(5000001),Plimit500000}

因为 ∣ a [ i ] − a [ j ] ∣ ∈ [ 0 , 500000 ] |a[i]-a[j]|\\in[0,500000] a[i]a[j][0,500000],所以最后枚举答案的范围是 [ 1 , 500001 ] [1,500001] [1,500001]

代码:

// Problem: Hash Function
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/11166/H
// Memory Limit: 524288 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#include<complex>
#define cp complex < double >
#define lowbit(x) (x&-x)
using namespace std;
const double pi=acos(-1);
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
	T f=1;x=0;
	char ch=getchar();
	while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	x*=f;
}
template<typename T>
inline void write(T x)
{
	if(x<0){x=~(x-1);putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;

int lena=0,lenb=0,n,res[N<<2];
 
cp F[N<<2],G[N<<2],arr[N<<2],inv[N<<2];
 
void init()
{
    for (int i=0;i<n;i++)
    {
        arr[i]=cp(cos(2*pi*i/n),sin(2*pi*i/n));
        inv[i]=conj(arr[i]);
    }
}
void FFT(cp *a,cp *arr)
{
    int lim=0;
    while ((1<<lim)<n) lim++;
    for (int i=0;i<n;i++)
    {
        int t=0;
        for (int j=0;j<lim;j++)
            if ((i>>j) & 1) t|=1<<(lim-j-1);
        if (i<t) swap(a[i],a[t]);
    }
    for (int l=2;l<=n;l*=2)
    {
        int m=l/2;
        for (cp *buf=a;buf!=a+n;buf+=l)
            for (int i=0;i<m;i++)
            {
                cp t=arr[n/l*i]*buf[i+m];
                buf[i+m]=buf[i]-t;
                buf[i]+=t;
            }
    }
}
int main()
{
#ifndef ONLINE_JUDGE
//	freo

以上是关于2021牛客多校1 - Hash Function(思维+FFT)的主要内容,如果未能解决你的问题,请参考以下文章

[Nowcoder] Browser Games-2021牛客多校10-A | Hash /压缩Trie

2021牛客多校1 B Ball Dropping

2021牛客多校8 D.OR(位运算)

2021牛客多校5 B Boxes

2021牛客多校8 D OR

2021牛客多校5 H Holding Two