CFP2123G Modular Sorting 学习笔记

CFP2123G Modular Sorting 学习笔记

Luogu Link

题意简述

给定一个整数 \(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;
}
posted @ 2025-08-24 15:00  矞龙OrinLoong  阅读(9)  评论(0)    收藏  举报