Luogu P5497 [LnOI2019SP] 龟速单项式变换(SMT) 题解 [ 黄 ] [ 构造 ] [ 前缀和 ] [ 鸽巢原理 ]

龟速单项式变换:鸽巢原理好题。

显然题意等效于能否构造一个长度为 \(n\) 的数列,使得某段子区间的和为 \(m\) 的倍数。

因为我们不在意数字的具体值为多少,所以仅对\(m\) 意义下的数列考虑。

为了刻画子区间和的条件,我们把数列转化为模 \(m\) 意义下的前缀和数列,则此时如果某两个位置的前缀和相等,则说明这个数列不合法。注意此处还蕴含一个 \(0\) 的前缀和元素

因此我们直接对前缀和序列进行构造,因为要保证所有前缀和元素都不相同,所以根据鸽巢原理,当 \(n> m\) 的时候,一定可以构造出一组合法解,否则一定会有前缀和元素重复。

时间复杂度 \(O(1)\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
int main()
{
    //freopen("sample.in","r",stdin);
    //freopen("sample.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll n,m;
    cin>>n>>m;
    if(n>=m)cout<<"YES";
    else cout<<"NO";
    return 0;
}
posted @ 2025-06-15 19:20  KS_Fszha  阅读(8)  评论(0)    收藏  举报