首页 > 其他分享 >CF995E Number Clicker

CF995E Number Clicker

时间:2023-12-16 20:34:29浏览次数:27  
标签:int void CF995E Number v1 Clicker 操作 mod define

Number Clicker

Luogu CF995E

题面翻译

小 y 在玩数学游戏,他有三种变化方式:

  1. 将该数 \(+1\);
  2. 将该数 \(-1\)
  3. 将该数变成他的逆元(即 \(p-2\) 次幂),当然,我们所有操作都是在 \(\bmod\ p\) 意义下的

现在小 h 知道了变换前的数 \(u\) 和变换后的数 \(v\),给定模数 \(p\) 保证是质数,他想知道怎么在 \(200\) 次操作之内得到 \(v\)。

\(p\le 10^9+9\)

Solution

尝试去找了一下三种操作之间有什么规律,然后发现确实没什么规律……

考虑构造一种操作,使它与题目要求的变化方式等价。由于存在逆元,所以我们将这个数表示成为 \(\dfrac a b\)。那么操作 \(1\) 对应 \(\dfrac {a+b}{b}\),操作 \(2\) 对应 \(\dfrac {a-b}{b}\),操作 \(3\) 对应 \(\dfrac b a\)。发现这个操作很像辗转相除法,所以考虑使用更相减损法来做这道题。

因为操作 \(1\) 和操作 \(2\) 是可逆的,并且操作 \(3\) 和操作 \(3\) 也是可逆的,所以可以考虑将变换前的数 \(u\) 和变换后的数 \(v\) 都变换成为一个数字后然后将一个操作序列反过来。不妨将这个数字设成 \(0\)。那么就是运用更相减损法将 \(u\) 和 \(v\) 分别变成 \(0\)。

初始的 \(a,b\) 并不好确认,所以可以直接随机 \(a\) 的取值,然后计算 \(b\)。如果直接使用更相减损法可能会直接超时,所以可以先使用辗转相除法计算步数,如果总步数 \(\le 200\) 就使用更相减损法构造答案。

复杂度 \(\mathcal O(\text{松松松})\)。

Code
// Cirno is not baka!
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = (a); i <= (int)(b); ++i)
#define Rof(i, a, b) for (int i = (a); i >= (int)(b); --i)
#define All(x) x.begin(), x.end()
#define pii pair<int, int>
#define fi first
#define se second
#define i64 long long
#define mkp make_pair
// #define int long long
#define epb emplace_back
using namespace std;

const int _N = 1e6 + 5, inf = 1e9;
template<typename T> void Max(T &x, T y) {x = max(x, y);}
template<typename T> void Min(T &x, T y) {x = min(x, y);}
#ifdef CIRNO
template<typename T> void Debug(T x) {cerr << x << '\n';}
template<typename T, typename ...Args> void Debug(T x, Args ...args) {cerr << x << ' '; Debug(args...);}
template<typename T> void Debug(vector<T> v) {for (T x: v) cerr << x << ' '; cerr << '\n';}
#else
#define Debug(...)
#endif

namespace BakaCirno {
    mt19937 rnd(9);
    #define Rand(l, r) uniform_int_distribution<>(l, r)(rnd)
    int A, B, mod;
    int Calc(int a, int b) {
        if (b == 0) return 0;
        return Calc(b, a % b) + a / b + 1;
    }
    vector<int> GetPath(int a, int b) {
        vector<int> res;
        while (b) {
            if (a < b) res.epb(3), swap(a, b);
            else res.epb(2), a -= b;
        }
        return res;
    }
    void _() {
        cin >> A >> B >> mod;
        while (true) {
            int v1 = Rand(1, mod - 1), v2 = Rand(1, mod - 1);
            if (Calc(1ll * v1 * A % mod, v1) + Calc(1ll * v2 * B % mod, v2) <= 200) {
                vector<int> r1 = GetPath(1ll * v1 * A % mod, v1),
                            r2 = GetPath(1ll * v2 * B % mod, v2);
                reverse(All(r2));
                cout << r1.size() + r2.size() << '\n';
                for (int x: r1) cout << x << ' ';
                for (int x: r2) cout << (x < 3 ? 3 - x : 3) << ' ';
                cout << '\n';
                break;
            }
        }
    }
}

void File(const string file) {
    freopen((file + ".in").c_str(), "r", stdin);
    freopen((file + ".out").c_str(), "w", stdout);
}
signed main() {
    // File("");
    cin.tie(0)->sync_with_stdio(0); int T = 1;
    // cin >> T;
    while (T--) BakaCirno::_();
}

标签:int,void,CF995E,Number,v1,Clicker,操作,mod,define
From: https://www.cnblogs.com/hanx16msgr/p/17908320.html

相关文章

  • [Codeforces] CF1744E1 Divisible Numbers (easy version)
    CF1744E1DivisibleNumbers(easyversion)题意给你四个数\(a,b,c,d\),你需要找出一组\(x,y\)使得\(a<x\leqc,b<y\leqd\)并且\(x\cdoty\)能被\(a\cdotb\)整除,如果没有输出-1-1。思路最暴力的思路肯定是枚举,更肯定的一点是会TLE但是注意到,如果\(x\)一定,那么他......
  • Unhandled exception. System.IO.IOException: The configured user limit (128) on t
    现象:Unhandledexception.System.IO.IOException:Theconfigureduserlimit(128)onthenumberofinotifyinstanceshasbeenreached,ortheper-processlimitonthenumberofopenfiledescriptorshasbeenreached.atSystem.IO.FileSystemWatcher.StartRaisi......
  • Smith Number
    题目Givenanumbern,thetaskistofindoutwhetherthisnumberisaSmithnumberornot.ASmithnumberisacompositenumberwhosesumofdigitsisequaltothesumofdigitsofitsprimefactors.Example1:Input:n=4Output:1Explanation:Thesum......
  • 转:ROW_NUMBER() OVER函数的基本用法
    ROW_NUMBER()OVER函数的基本用法 分组后排序    在oracle中分组倒叙排序,取出每一组的第一个值,如何通过ROW_NUMBER()OVER实现 ChatGPTChatGPT在Oracle中,你可以使用ROW_NUMBER()窗口函数结合PARTITIONBY和ORDERBY子句来实现......
  • CMC-ORACLE-函數row_number() over(partition by )函数用法
    row_number()over(partitionby)函数用法row_number()over(partitionby),作为oracle常用的分析函数,身为数据开发时必须要掌握的。不过一段时间不用,难免会有些忘记,今天整理一下一些场景下的用法。现有表(test_rownumber)有如下数据:RUSER(用户名)RID(用户编号)RSAL(用户消费)RD......
  • C - Sum of Numbers Greater Than Me
    C-SumofNumbersGreaterThanMehttps://atcoder.jp/contests/abc331/tasks/abc331_c 思路由于值可以是重复的,需要记录每出现的值对应的位置,记录在map<int,vector<int>>valpos;此处利用了mapkey的自动排序属性,把所有值进行从小到大做了排序,然后根据valpos......
  • CF55D Beautiful numbers
    题意给定序列\(S\)。求满足以下性质的\(S\)的排列的数量:\(\max_{j=1}^{i-1}s_j\ge2\timess_i\)或\(\max_{j=1}^{i-1}2\timess_j\les_i\)。Sol排个序先。设\(f_i\)表示我们从小到大往\(s\)里面填数,现在填的最大值为\(s_i\)的方案数。不难......
  • 无涯教程-Erlang - Numbers(数字)
    在Erlang中,有两种数字类型:整数(integers)和浮点数(floats)。整数示例:-module(helloLearnfk).-export([start/0]).start()->io:fwrite("~w",[1+1]).上面程序的输出如下:2浮点数示例:-module(helloLearnfk).-export([start/0]).start()->io:fwrite("~......
  • 数仓性能调优:row_number() over(p)-rn=1性能瓶颈发现和改写套路
    本文分享自华为云社区《GaussDB(DWS)性能调优:row_number()over(p)-rn=1性能瓶颈发现和改写套路》,作者:Zawami。1、改写场景本套路应用于子查询中含有row_number()over(partitionbyorderby)rn,并仅把rn列用于分类排序后筛选最大值的场景。2、性能分析GaussDB中SQL语句的执......
  • apache的数字工具类NumberUtils
    org.apache.commons.lang3.NumberUtils<!--StringUtils、NumberUtils等工具类--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version></de......