CFP2123G Modular Sorting 学习笔记
CFP2123G Modular Sorting 学习笔记
题意简述
给定一个整数 \(m\) 和一个长为 \(n\) 序列 \(A\),运算均在模 \(m\) 意义下进行。
给定 \(q\) 个操作。
1 i x:单点赋值。2 k:若你可以指定任意自然数个元素 \(a_i\),将其修改为 \((a_i+x_i\times k)\),其中 \(x_i\) 自定,能否使 \(a\) 单调不降。
多测。\(\sum n,\sum q\le 10^5\)。
做法解析
显然,所有 \(a_i\) 都可以加上任意个 \(d=\text{gcd}(k,m)\)。然后呢?我们怎么去衡量选择给 \(a_i\) 赋值,使其既能单调不降又尽量小?
很简单:对于 \(a_i\),我们把它写成 \(p_i+d\times x_i\) 的形式。如果 \(p_i\ge p_{i-1}\),那么 \(x_i=x_{i-1}\) 最优。否则我们就得让 \(x_i\) 等于 \(x_{i-1}+1\)。你发现 \(x_i\) 最大为 \(\frac{m}{d}-1\),所以你贪心地选完之后看看超了没。
代码实现
#include <bits/stdc++.h>
using namespace std;
using namespace obasic;
const int MaxN=1e5+5,MaxM=5e5+5,MaxD=2e2+5;
int N,M,Q,A[MaxN],Opt,X,Y;
int gcnt,G[MaxD],C[MaxD],cg;
map<int,int> mp;
void mian(){
readis(N,M,Q);mp.clear(),gcnt=0;
for(int i=1;i<=N;i++)readi(A[i]);
for(int i=1,cg,ch,cid;i<=Q;i++){
readis(Opt,X);
if(Opt==1){
readi(Y);
for(int j=1;j<=gcnt;j++){
cg=G[j];
if(X>1)C[j]-=(A[X-1]%cg>A[X]%cg);
if(X>1)C[j]+=(A[X-1]%cg>Y%cg);
if(X<N)C[j]-=(A[X]%cg>A[X+1]%cg);
if(X<N)C[j]+=(Y%cg>A[X+1]%cg);
}
A[X]=Y;
}
if(Opt==2){
cg=gcd(M,X),ch=M/cg;
if(!mp[cg]){
G[++gcnt]=cg,mp[cg]=gcnt,C[gcnt]=0;
for(int i=1;i<N;i++)C[gcnt]+=(A[i]%cg>A[i+1]%cg);
}
cid=mp[cg];puts(C[cid]<ch?"YES":"NO");
}
}
}
int Tcn;
int main(){
readi(Tcn);
while(Tcn--)mian();
return 0;
}
浙公网安备 33010602011771号