首页 > 其他分享 >Magical Palette( The 2024 ICPC Asia Shenyang Regional Contest)

Magical Palette( The 2024 ICPC Asia Shenyang Regional Contest)

时间:2024-12-04 13:02:57浏览次数:9  
标签:Palette gcd Contest cdot 复杂度 Regional ij include mod

Magical Palette( The 2024 ICPC Asia Shenyang Regional Contest)

在这里插入图片描述

题目描述:体面总结

小白兔有一个魔法调色板,调色板是一个 ( n × m ) (n \times m) (n×m) 的网格。
在每一行的左边挤出一种颜料 ( a 1 , a 2 , … , a n ) (a_1, a_2, \ldots, a_n) (a1​,a2​,…,an​),在每一列的上方挤出一种颜料 ( b 1 , b 2 , … , b m ) (b_1, b_2, \ldots, b_m) (b1​,b2​,…,bm​)。
在网格的第 (i) 行第 (j) 列的颜色是通过计算公式:
c i j = ( a i ⋅ b j ) m o d    ( n ⋅ m )   c_{ij} = (a_i \cdot b_j) \mod (n \cdot m) \ cij​=(ai​⋅bj​)mod(n⋅m) 

小白兔希望网格中每一个颜色 ( c i j ) (c_{ij}) (cij​) 都不相同。

小白兔希望网格中每一个颜色 (c_{ij}) 都不相同。

你的任务是判断是否可能实现,并在可能时输出合适的颜料 ( a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1​,a2​,…,an​) 和 ( b 1 , b 2 , … , b m b_1, b_2, \ldots, b_m b1​,b2​,…,bm​)。


首先第一个规律你得搞明白,当两条边gcd不等于1时,你根本就找不到答案!!!

这点非常的重要!!!

当你玩了两幅图后,你可能就有点感觉,比方说:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

你可能发现了一点规律,就是有一条边上的数是等差数列,似乎可行,但是当你玩这个样例,仿佛有点毛病
在这里插入图片描述

这时,你可以慢慢推理,发现仿佛将长宽上的数都变为等差数列就可行

打表试试没啥问题就好

但是注意一点!!!

当有一条边等于1,或两条边都为1时,特判!!!非常重要
因为题目中有句话叫做 ( 0 ≤ a < n m ) (0 \leq a < nm) (0≤a<nm)
太阴险了
在这里插入图片描述
在这里插入图片描述

思路分析

  1. 网格中颜色不同的充要条件

    • 网格中所有颜色 ( c i j c_{ij} cij​) 必须覆盖从 (0) 到 ( n ⋅ m − 1 n \cdot m - 1 n⋅m−1) 的所有整数。
    • 这需要 ( c i j = ( a i ⋅ b j c_{ij} = (a_i \cdot b_j cij​=(ai​⋅bj​) m o d    ( n ⋅ m ) \mod (n \cdot m) mod(n⋅m)) 对 (i) 和 (j) 的所有组合是互异的。
  2. 关键观察

    • 如果 ( gcd ⁡ ( n , m ) = 1 \gcd(n, m) = 1 gcd(n,m)=1 ),可以证明通过选择合适的 ( a i a_i ai​) 和 ( b j b_j bj​),能确保所有颜色互异。
    • 如果 ( gcd ⁡ ( n , m ) > 1 \gcd(n, m) > 1 gcd(n,m)>1 ),则无法满足要求,因为颜色必然出现重复。
  3. 构造方法(当 ( gcd ⁡ ( n , m ) = 1 \gcd(n, m) = 1 gcd(n,m)=1)):

    • 设 ( a i = ( i ⋅ m + 1 a_i = (i \cdot m + 1 ai​=(i⋅m+1) m o d    ( n ⋅ m ) \mod (n \cdot m) mod(n⋅m)),其中 ( i ∈ [ 1 , n ] i \in [1, n] i∈[1,n])。
    • 设 ( b j = ( j ⋅ n + 1 ) m o d    ( n ⋅ m ) b_j = (j \cdot n + 1) \mod (n \cdot m) bj​=(j⋅n+1)mod(n⋅m)),其中 ( j ∈ [ 1 , m ] j \in [1, m] j∈[1,m])。
    • 这样生成的 ( a i a_i ai​) 和 ( b j b_j bj​) 能保证所有 ( c i j c_{ij} cij​) 不同。
  4. 复杂度分析

    • 构造方法的时间复杂度为 ( O ( n + m ) O(n + m) O(n+m))。
    • 对于多个测试用例,总复杂度为 ( O ( T ⋅ ( n + m ) ) O(T \cdot (n + m)) O(T⋅(n+m))),且输入规模限制保证效率。

代码实现

#include <map>
#include <set>
#include <fstream>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdio>
#include <bitset>
#include <iomanip>
#define endl '\n'
#define int long long
#define Max(a, b) (((a) > (b)) ? (a) : (b))
#define Min(a, b) (((a) < (b)) ? (a) : (b))
#define BoBoowen ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;

int n, m;

signed main()
{
    int T;
    cin >> T;
    while (T--)
    {
        cin >> n >> m;
        if (__gcd(n, m) == 1)
        {
            cout << "Yes" << endl;
            for (int i = 1; i <= n; i++)
            {
                cout << (i * m + 1) % (m * n) << " ";
            }
            cout << endl;
            for (int j = 1; j <= m; j++)
            {
                cout << (j * n + 1) % (m * n) << " ";
            }
            cout << endl;
        }
        else
        {
            cout << "No" << endl;
        }
    }
}

详细说明

  1. 输入输出格式

    • 输入:一个整数 (T),表示测试用例数。接下来 (T) 行,每行两个整数 (n) 和 (m)。
    • 输出:对每个测试用例,输出 “Yes” 和两行数组 (a) 和 (b) 或直接输出 “No”。
  2. 逻辑说明

    • 使用 (\gcd) 判断是否存在解。
    • 如果存在解,利用构造公式生成满足条件的 (a_i) 和 (b_j)。
  3. 样例解释

    • 样例输入:

      2
      2 3
      2 2
      
    • 样例输出:

      Yes
      1 2
      1 3 5
      No
      
    • 解释

      • 第一个测试用例中,( gcd ⁡ ( 2 , 3 ) = 1 \gcd(2, 3) = 1 gcd(2,3)=1),存在解。通过公式生成 (a = [1, 2]),(b = [1, 3, 5])。
      • 第二个测试用例中,( gcd ⁡ ( 2 , 2 ) = 2 > 1 \gcd(2, 2) = 2 > 1 gcd(2,2)=2>1),无解。

复杂度评估

  • 每次构造 (a) 和 (b) 的复杂度为 ( O ( n + m ) O(n + m) O(n+m))。
  • 总复杂度为 ( O ( sum of all  ( n + m ) ) ≤ 1 0 6 O(\text{sum of all } (n + m)) \leq 10^6 O(sum of all (n+m))≤106),能够在时间限制内运行。

总结

  • 通过 (\gcd) 快速判断是否存在解。
  • 利用简单的线性公式构造满足条件的解。
  • 算法高效且易于实现,适合大规模输入场景。

标签:Palette,gcd,Contest,cdot,复杂度,Regional,ij,include,mod
From: https://blog.csdn.net/2301_80379979/article/details/144234180

相关文章

  • AtCoder Beginner Contest 382-E
    Problem有无数包牌,每包有\(N\)张牌。在每一包牌中,第\(i\)张牌是稀有牌,概率为\(P_i\%\)。每张牌是否稀有与其他牌是否稀有无关。逐一打开包装,并获得每包中的所有卡片。当你一直开包直到总共获得至少\(X\)张稀有卡牌时,求你开包的预期次数。Constraints\(1\leqN\leq5......
  • AtCoder Beginner Contest 382 Solution
    A-DailyCookie(abc382A)题目大意给定一个长度为N的字符串,有很多.和@,一共有D天,每天会使一个@变成.,问D天之后有几个.解题思路数一下有几个.,答案会加D个.。代码voidsolve(){intn,d;strings;cin>>n>>d>>s;cout<<count(s.begin(),s.end(),'.......
  • AtCoder Beginner Contest 380 Solution
    A-1232336个数问是不是1个1,2个2,3个3#include<bits/stdc++.h>usingnamespacestd;inta[4];intmain(){strings;cin>>s;for(inti=0;i<s.size();i++)a[s[i]-'0']++;if(a[1]==1&&a[2]==2......
  • AtCoder Beginner Contest 382 赛后复盘
    abc381的赛后总结不见了。(人话:没写)A-B模拟即可C因为好吃的会被前面的人吃掉,后面的人只能捡垃圾吃,所以实际上能吃东西的\(a\)成单调递减。所以我们直接二分在哪个区间即可,时间复杂度\(O(m\logn)\)。点击查看代码#include<bits/stdc++.h>#definelllonglong#de......
  • AtCoder Beginner Contest 382
    A-DailyCookie题意给定长为\(n\)的串,“.”代表空,“@”代表饼干,一天吃一块饼干,问\(d\)天后有几个格子是空的。思路模拟。代码点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>pii;constintmxn=1e......
  • The 2024 ICPC Kunming Invitational Contest
    Preface周五去昆明特意买了动车,就为了在车上也能VP一场找了半天不知道打什么,最后决定去昆明不如把今年的昆明邀请赛补一下,遂开了这场前期可以说还是十分顺遂的,2h15min的时候就过了7个题,其中还早早地过了后期题H但后面被J和L小卡了一手,最后通过换题成功把两个题都过......
  • Atcoder Beginner Contest 330 题解
    前言过于水的一场。ACountingPasses题面给出一个长度为\(n\)的序列\(a\),求出\(a\)之中大于等于\(l\)的数个个数。\(1\len\le100,1\lea_i\le1000,1\lel\le1000\)。制約入力は全て整数$1\\le\N\\le\100$$1\\le\L\\le\1000$$0\\le\A_i\\le......
  • 每日一题:https://codeforces.com/contest/1700/problem/B
    题目链接:https://codeforces.com/contest/1700/problem/B#include<iostream>#include<string.h>#include<string>#include<cmath>#include<algorithm>usingnamespacestd;intmain(){intu;cin>>u;for(inti=1;i......
  • 每日一题:https://codeforces.com/contest/1999/problem/D
    题目链接:https://codeforces.com/contest/1999/problem/D#include<iostream>#include<string>#include<vector>usingnamespacestd;intmain(){intn;cin>>n;for(;n>0;n--){stringarr1;stringarr2;......
  • AtCoder Beginner Contest 381
    省流版A.按题意判断即可B.按题意判断即可C.枚举/的位置,然后分别向左右找到最长的1串和2串,然后取最小值即可D.讨论起始位置的奇偶性,然后用双指针,每两个字符每两个字符,维护出现的次数为2,两种情况取最大值即可E.答案为所有/的左右12个数的最小值的最大值,注意到个数随着/......