CF1746F
Kazaee
题面翻译
题目描述
给出一个长度为 \(n\) 的数组 \(a\) 和以下两种操作:
- \(1\ i\ x\):将 \(a_i\) 修改为 \(x\)。
- \(2\ l\ r\ k\):询问在数组区间 \([l, r]\) 内是否每个出现过的正整数的出现次数都是 \(k\) 的倍数。(建议参照样例理解)若是则输出
YES,若否则输出NO。
输入格式
第一行两个整数 \(n\)、\(q\),表示数组长度和操作数。
第二行 \(n\) 个整数,为数组 \(a\) 中的元素。(下标从1开始)
之后 \(q\) 行,每行一个询问。
输出格式
对于每个操作2,给出相应答案(YES 或 NO)。
样例 #1
样例输入 #1
10 8
1234 2 3 3 2 1 1 2 3 4
2 1 6 2
1 1 1
2 1 6 2
2 1 9 2
1 10 5
2 1 9 3
1 3 5
2 3 10 2
样例输出 #1
NO
YES
NO
YES
YES
神仙题!!!
tag 是树状数组+HASH
其实我也想到了思路:
很容易想到出现次数是k的倍数的必要条件是 区间和是k的倍数
但是若是初始序列单一确定的值很容易构造出反例
所以我们用随机化的思想
在保证相同的数赋值随机值相同的情况下多次随机
若都满足 那就期望正确
具体代码的实现:先对操作离线处理 存入所有的值后去重找位置记录下来 就构成了多个相同数的集合 然后随机化30次左右就行了
点击查看代码
#include<bits/stdc++.h>
#include<ctime>
using namespace std;
#define int long long
mt19937 rnd(time(NULL));
const int N=300005;
const int mod=1e9+7;
int a[N+5],tr[N+5],n,q,m,b[(N<<1)+5],op[N+5],pos[N+5],x[N+5],l[N+5],r[N+5],k[N+5],ans[N+5],val[2*N+5],pre[N+5];//离线操作
int lowbit(int x)
{
return x&(-x);
}
void add(int n,int p,int x)
{
for(;p<=n;p+=lowbit(p))
tr[p]+=x;
}
int query(int p)
{
int sum=0;
for(;p;p-=lowbit(p))
sum+=tr[p];
return sum;
}
signed main()//对相同的数赋予相同的随机值
{
cin>>n>>q;
srand(time(NULL));
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
b[++m]=a[i];
}
for(int i=1;i<=q;i++)//对操作离线处理
{
scanf("%lld",&op[i]);
if(op[i]==1)
{
scanf("%lld",&pos[i]);
scanf("%lld",&x[i]);
b[++m]=x[i];
}
else
{
scanf("%lld%lld%lld",&l[i],&r[i],&k[i]);
if((r[i]-l[i]+1)%k[i]==0)ans[i]=1;
}
}
sort(b+1,b+m+1);
m=unique(b+1,b+m+1)-(b+1);//去重前若两个不同位置的数相等那么去重后位置就相同
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+m+1,a[i])-b;
for(int i=1;i<=q;i++)
if(op[i]==1)
x[i]=lower_bound(b+1,b+m+1,x[i])-b;
for(int kk=1;kk<=30;kk++)
{
memset(tr,0,sizeof(tr));
for(int i=1;i<=m;i++)val[i]=rnd()%mod;
for(int i=1;i<=n;i++)
{
pre[i]=a[i];
add(n,i,val[a[i]]);
}
for(int i=1;i<=q;i++)
{
if(op[i]==1)
{
add(n,pos[i],val[x[i]]-val[pre[pos[i]]]);//点修改 要算出差值
pre[pos[i]]=x[i];
}
else
{
ans[i]&=(query(r[i])-query(l[i]-1))%k[i]==0;
}
}
}
for(int i=1;i<=q;i++)
{
if(op[i]==2)
{
if(ans[i])printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
此生无悔入OI 来生AK IOI

浙公网安备 33010602011771号