首页 > 其他分享 >[ARC112F] Die Siedler 题解

[ARC112F] Die Siedler 题解

时间:2024-10-07 21:49:05浏览次数:8  
标签:Siedler res 17 min int 题解 Die 我们 根号

智慧题。

思路

考虑第二种操作。

我们会想到,我们可以先把所有牌转化成第一种牌。

即:

\[one=\sum_{i=1}^n\prod_{j=1}^i 2^{j-1}(j-1)!c_i \]

这就是第一种牌的数量。

然后考虑,我们可以将第一种牌转化为第一种牌,花费的代价为:

\[g=(\prod_{i=1}^n 2^{i-1}(i-1)!)-1 \]

相当于对 \(g\) 取模。

类似的,我们可以把所有牌包也转化为 \([0,g)\) 中的一个整数。

我们现在,就需要用这些东西不断的去凑。

假如我们最初是 \(s\),想要凑出 \(t\)。

那么依据裴蜀定理。

要求:

\[\gcd(s_i,g)|(t-s) \]

这个怎么解决呢。

我们可以先让 \(p=\gcd(s_i,g)\)。

然后考虑根号分治。

  1. \(p> \sqrt g\)

    我们发现在这种情况中,我们暴力枚举 \(s+p\times i\),只有根号种取值,我们暴力计算每一个数的答案,取个 \(\min\) 就可以了。

  2. \(p\le \sqrt g\)

    在这种情况中,由于 \(p\) 很小,我们可以求出每一个余数在 \([0,p)\) 中的答案。

    具体的我们可以让每个点 \(i\) 往后连 \(n\) 条边,表示加一张牌。

    然后就是同余最短路形式,转圈解决即可。

打表发现实际次数远不到根号,所以能过。

Code

#include <bits/stdc++.h>
using namespace std;

#define int long long

int n, m, bg;
int s[55][17];
int f[17];
int b[17];
int c[17];
int a[2000010];
int g[2000010];

inline int sol(int x) {
  if (x == 0) return 1e9;
  int res = 0;
  for (int i = n; i >= 1; i--)
    res += x / f[i], x %= f[i];
  return res;
}

signed main() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) cin >> c[i];
  for (int i = 1; i <= m; i++)
    for (int j = 1; j <= n; j++)
      cin >> s[i][j];
  f[1] = 1;
  for (int i = 2; i <= n; i++)
    f[i] = f[i - 1] * (i - 1) * 2;
  int g = f[n] * n * 2 - 1;
  int l = f[n] * n * 2 - 1;
  for (int i = 1; i <= m; i++) {
    int res = 0;
    for (int j = 1; j <= n; j++)
      res += s[i][j] * f[j];
    g = __gcd(g, res);
  }
  for (int i = 1; i <= n; i++) bg += c[i] * f[i];
  if (g <= 1300000) {
    bg %= g;
    for (int i = 0; i < g; i++) a[i] = 7e18;
    for (int i = 1; i <= n; i++) f[i] = f[i] % g;
    for (int i = 1; i <= n; i++) a[f[i]] = 1;
    for (int i = 1; i <= n; i++) {
      int lim = __gcd(f[i], g);
      for (int k = 0; k < g; k += lim) {
        for (int j = 0; j < lim; j++) {
          int l = j + k, r = j + k + f[i];
          if (r >= g) r -= g;
          a[r] = min(a[r], a[l] + 1);
        }
      }
      for (int k = 0; k < g; k += lim) {
        for (int j = 0; j < lim; j++) {
          int l = j + k, r = j + k + f[i];
          if (r >= g) r -= g;
          a[r] = min(a[r], a[l] + 1);
        }
      }
    }
    cout << a[bg] << "\n";
  } else {
    int ans = 7e18;
    for (int i = bg % g; i <= l; i += g) {
      ans = min(ans, sol(i));
    }
    cout << ans << "\n";
  }
}

标签:Siedler,res,17,min,int,题解,Die,我们,根号
From: https://www.cnblogs.com/JiaY19/p/18450728

相关文章

  • P1437 [HNOI2004] 敲砖块 题解
    初拿到手感觉限制太多了,不好硬做,于是开始观察。若要取某一个数,我们要取其左上右上两个数,而这两个数又要取上面三个数,所以取一个数的前提条件其实是取这一个三角形。举例2234582712236493比如我要取第3行的6,我首先要取7和12,要取7和12,首先要取3,4,5,所以一层层拓展......
  • 鲁的女孩 题解
    题意给两个数列,对它进行排列,使得对应两数的和的最大值最小。题解贪心,先将\(a\)、\(b\)排个序(先不考虑时间)。将\(a_1\)与\(a_n\)匹配。\(a_2\)与\(a_{n-1}\)匹配。……取最大值即可。考虑到\(n\le10^5\),不可以暴力枚举。但是\(a,b\le100\),可以开一个桶,......
  • 题解 QOJ1869【Power Station of Art】/ SS241006B【结论题】
    题解QOJ1869【PowerStationofArt】/SS241006B【结论题】PetrozavodskSummer2021.Day6.XJTUContest,GPofXJTUXXIIOpenCupnamedafterE.V.Pankratiev,GrandPrixofXi'an题目描述给出一个无向图,每个点有点权\(a\)和颜色\(c\),其中颜色只会有红蓝两种。......
  • CF131C题解
    传送门:https://codeforces.com/problemset/problem/134/C关注到题目的两个限制:1.一个人只能与另外同一人交换一张卡牌。2.一个人只能交换自己原来颜色的卡牌。对于2条限制条件,显然有贪心思路:尽量让更多的人手持原有的卡牌。对于当前待交换的卡牌,一种构造思路,我们每次贪心选取......
  • 伊吹萃香 题解
    题意(很复杂,真的不想概括,以下是原题面)在幻想乡,伊吹萃香是能够控制物体密度的鬼王。因为能够控制密度,所以萃香能够制造白洞和黑洞,并可以随时改变它们。某一天萃香闲着无聊,在妖怪之山上设置了一些白洞或黑洞,由于引力的影响,给妖怪们带来了很大的麻烦。于是他们决定找出一条消耗体力......
  • CF1117E Decypher the String题解
    传送门神奇的题。这是一道交互题。给定一个字符串\(s\),我们拥有若干操作,但是你不知道,第\(i\)个操作形如\(a_i,b_i\)表示交换字符串\(s\)中的第\(a_i\)位和\(a_j\)位。比如操作序列依次为\((1,2),(2,3)\),给定字符串为xyz。那么我们执行第一次操作后......
  • 题解 QOJ2559【Endless Road】/ SS241006D【套路题】
    PetrozavodskWinter2022.Day2.KAISTContest+KOITST2021XXIIOpenCupnamedafterE.V.Pankratiev,GrandPrixofDaejeon题目描述现在有\(10^9\)个花盆,依次编号为\(1,2,\dots,10^{9}\)。给定\(n\)个二元组\(L_i,R_i(L_i<R_i)\),我们将进行\(n\)次以下操......
  • CF722F Cyclic Cipher 题解
    传送门给定\(n\)个数列,第\(i\)个数列包含\(k_i\)个不超过\(m\)的互不相同的正整数(从\(1\)开始标号)。每一秒将每个数列中的数左移一个位置(即将每个数的下标\(-1\),下标\(1\)的数下标变为\(k_i\)),并记录由每个数列的第一个数组成的序列。\(10^{100}\)秒过......
  • [NOIP2023] 双序列拓展 题解
    qaq首先我们考虑其实这个条件就是要满足\(f\)严格比\(g\)大或\(f\)严格比\(g\)小。在这里只讨论大于。然后考虑到对于一个\(i\)如果不满足,我们可以把对应数组向右移一位看是否满足,如果还是不满足就无解了。考虑对于现在满足的\(i\),我们可以分别把两个指针向右移一......
  • EGOI2024 简单题解
    Day1T1InfiniteRace由于只有重复超过一个人才肯定是跑过一圈的,所以只用用一个数组做标记就可以了,每超过一次就打上标记,否则去掉标记。T2Bouquet定义\(dp[i]\)为,以第\(i\)种郁金香结尾的选法中最大可选的郁金香数量,易得状态转移方程为:\(dp[i]=max{dep[j]}+1(j<l_i\le......