CF1746F Kazaee 题解
CF1746F Kazaee 题解
题目描述
题目解法
看到题目能想到一个相当劣的树状数组做法:先离散化,然后对每个数开个树状数组,每次查询区间内每个数的个数。
这个做法相当劣,修改 \(O(\log{n})\),查询 \(O(n\log n)\),总的复杂度为 \(O(n^2 \log n)\) 无法通过本题。(空间也开不下)
好像还有一个 \(O(n^{\frac{5}{3} }\log n)\) 的莫队做法,但是也过不去...
所以就只能考虑乱搞。
我们考虑一个区间 \([l,r]\),如果每个出现过的正整数的出现次数都是 \(k\) 的倍数,那么一定有:
\[\sum^r_{i=l} a_i \equiv 0 \pmod k
\]
但是上述条件只是一个必要条件,并不是充分条件。
其错误率大概是 \(\frac{1}{k}\)。
考虑随机化。
序列 \(b_j\) 是将 \(a\) 序列中每个值随机分配了一个值域中的新值后生成的序列。
比如 \(a=\{1,2,2,4,3\}\),那么我们令 \(b_1=\{2,1,1,5,4\}\),\(b_2, b_3\) 同理。
如果对于所有的 \(T\) 个 \(b_j\),其均满足:
\[\sum^r_{i=l} b_{j,i}\equiv 0 \pmod k
\]
那么判断的错误率就是 \(\frac{1}{k^T}\)。
\(T\) 的取值就自行调参,\(T\) 过大会导致超时,\(T\) 过小会判断错误。
实现方法就是开 \(T\) 组树状数组。
用结构体和 vector 的树状数组被卡了,请各位注意卡常
Code
#include<bits/stdc++.h>
using namespace std;
#define maxn 300005
#define i64 long long
const int T=30;
template< typename T >inline void read(T &x)
{
char c=getchar();x=0;int f=0;
for(;!isdigit(c);c=getchar()) f|=(c=='-');
for(;isdigit(c);c=getchar()) x=((x<<3)+(x<<1)+(c^48));
x=f?-x:x;
}
template< typename T >inline void write(T x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10^48);
}
template< typename T,typename ... Args >
inline void read(T &_x, Args &... args)
{read(_x), read(args...);}
template< typename T,typename ... Args >
inline void write(T _x, Args ... args)
{ write(_x), write(args...);}
unordered_map<int, int> hsh;
int cnt=0;
i64 ta[T][maxn];
int dic[T][maxn<<1];
int val(int x, int t) {return dic[t][hsh.count(x)?(hsh[x]):(hsh[x]=++cnt)];}
void modify(int i, int v, int t) {for(;i<maxn;i+=i&-i) ta[t][i]+=v;}
i64 __qry(int i, int t) {i64 r=0; for(;i;i-=i&-i) r+=ta[t][i]; return r;}
i64 query(int l, int r, int t) {return __qry(r, t)-__qry(l-1, t);}
int lis[maxn];
#define rng for(int t=0;t<T;t++)
int main()
{
srand(time(0));
int n,q;
read(n, q);
rng for(int j=1;j<=n+q;j++) dic[t][j]=j;
rng random_shuffle(dic[t]+1, dic[t]+1+n+q);
// 赋随机值的方法被卡了,所以用 random_shuffle()
for(int i=1;i<=n;i++)
{
read(lis[i]);
rng modify(i, val(lis[i], t), t);
}
while(q--)
{
int opt, l, r, k;
read(opt);
if(opt==1)
{
read(l, r);
rng modify(l, val(r, t)-val(lis[l], t), t);
lis[l]=r;
}
else
{
read(l, r, k);
if((r-l+1)%k) {puts("NO");continue;}
int tag=0;
rng if(query(l, r, t)%k) {tag=1; break;}
puts(tag?"NO":"YES");
}
}
}

浙公网安备 33010602011771号