首页 > 其他分享 >P9017 [USACO23JAN] Lights Off G 题解

P9017 [USACO23JAN] Lights Off G 题解

时间:2023-07-27 16:47:23浏览次数:44  
标签:std P9017 cdot 题解 贡献 Lights 序列 操作 include

Description

给定正整数 \(N\),和两个长为 \(N\) 的 \(01\) 序列 \(a\) 和 \(b\)。定义一次操作为:

  1. 将 \(b\) 序列中的一个值翻转(即 \(0\) 变成 \(1\),\(1\) 变成 \(0\),下同)。
  2. 对于 \(b\) 序列中每个值为 \(1\) 的位置,将 \(a\) 序列中对应位置的值翻转。
  3. 将 \(b\) 序列向右循环移位 \(1\) 位。即若当前 \(b\) 序列为 \(b_1b_2\cdots b_{n}\),则接下来变为 \(b_{n}b_1b_2\cdots b_{n-1}\)。

有 \(T\) 次询问,对每一次询问,你需要回答出至少需要几次操作,才能使 \(a\) 序列中每一个位置的值都变为 \(0\)。

link

Solution

显然可以把 \(a,b\) 数组看成两个数,操作一就是对 \(b\) 的某一位取反,操作二就是让 \(a\) 异或 \(b\),操作三是让 \(b\leftarrow \left\lfloor \frac{b}{2} \right\rfloor\)。

容易发现操作数不超过 \(3n\),因为可以先用至多 \(n\) 次操作把 \(b\) 变成 \(0\)。然后每连续两次操作就让 \(b\) 的某一位变成 \(1\),把 \(a\) 的这一位消掉,然后 \(b\) 清空。

然而这样做是 \(O(T\cdot n^n)\) 的,过不了且没法优化。


观察可知,如果第 \(i\) 次操作将第 \(j\) 位异或 \(1\),总共进行 \(s\) 次操作,那么这次操作对最终 \(a\) 的贡献就是 \(j\sim j+s-i\) 这些位取反(在模 \(n\) 意义下)。

这样就可以 dp 了。

设 \(f_{i,j}\) 表示进行恰好 \(i\) 次操作,能否让 \(a\) 变成 \(j\),设 \(x\) 为任意一个模 \(n\) 意义下连续的长度为 \(1\) 的数组所对应的状态,那么就让 \(f_{i,j}\leftarrow f_{i-1,j\oplus x\oplus b}\)。

初始 \(f_{0,a}=1\),时间复杂度:\(O(T\cdot n\cdot 2^{n})\),过不了。


考虑把操作一的贡献和操作二、三的贡献拆开算。操作一所做的贡献就相当于初始 \(b=0\) 进行若干次操作对 \(a\) 的贡献,显然可以预处理,即设 \(f_{i,j}\) 表示 \(b\) 初始值为 \(0\),对 \(a\) 能否做出 \(j\) 的贡献。

设 \(x\) 为任意一个模 \(n\) 意义下连续的长度为 \(1\) 的数组所对应的状态,那么就让 \(f_{i,j}\leftarrow f_{i-1,j\oplus x}\)。

而操作二、三就是对 \(b\) 进行这么多操作的异或和,枚举操作次数即可求得。

时间复杂度:\(O(n^2\cdot 2^n+Tn)\)。

具体实现细节见代码

Code

#include <cstdio>
#include <iostream>
#include <map>

// #define int int64_t

int n, a, b;
int f[100][1 << 20];

int shift(int x) {
  return (x >> 1) + (1 << n - 1) * (x & 1);
}

int tonum(std::string s) {
  int ret = 0;
  for (int i = 0; i < static_cast<int>(s.size()); ++i)
    ret = (ret << 1) + s[i] - '0';
  return ret;
}

int calc(int a, int b) {
  for (int i = 0; i <= 3 * n; ++i, b = shift(b)) {
    if (f[i][a]) return i;
    a ^= b;
  }
  return -1;
}

void prework() {
  f[0][0] = 1;
  for (int i = 1; i <= 3 * n; ++i) {
    int s = (1 << ((i - 1) % n + 1)) - 1;
    for (int j = 0; j < n; ++j, s = shift(s)) {
      for (int k = 0; k < (1 << n); ++k)
        f[i][k] |= f[i - 1][k ^ s];
    }
  }
}

void dickdreamer() {
  int t;
  std::cin >> t >> n;
  prework();
  for (; t; --t) {
    std::string s, t;
    std::cin >> s >> t;
    a = tonum(s), b = tonum(t);
    std::cout << calc(a, b) << '\n';
  }
}

int32_t main() {
#ifdef ORZXKR
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
  std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
  int T = 1;
  // std::cin >> T;
  while (T--) dickdreamer();
  // std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
  return 0;
}

标签:std,P9017,cdot,题解,贡献,Lights,序列,操作,include
From: https://www.cnblogs.com/Scarab/p/17585334.html

相关文章

  • CF938G Shortest Path Queries 题解
    目录题目链接题目分析为什么使用生成树建树对于异或贡献的分析code题目链接CF938G洛谷挂了只能交CF题目分析本题有以下几个关键点:为什么使用生成树建树首先根据\(WC2011\)我们发现可以使用\(dfs\)序来保存节点之间的关系但是我们发现本题目中存在加边删边操作不......
  • UVA10702 Travelling Salesman 题解
     UVA10702TravellingSalesman题解题面:有个旅行的商人,他每到一个的新城市,便卖掉所有东西再购买新东西,从而获得利润。从某城市A到某城市B有固定利润(B 到A 的利润可能不同)。已知城市可以重复到达,从S 点出发,经过T 个城市,有E个城市能作为终点,求最大的利润。先定义......
  • CF1053E-Euler Tour题解
    前言还是一道神仙题很难想题面luogu上copy的样例解释懒得翻,我觉得应该都看得懂样例吧。题面翻译现有一棵\(n\)个点的形态未知的树,给定其长度为\(2n-1\)的欧拉序的一部分请根据给出的残缺的欧拉序还原出一个完整的欧拉序或判断不存在这样的树输入中用非零数字表示欧拉......
  • P3704 [SDOI2017] 数字表格 题解
    一、题目描述:用$f_i$表示斐波那契数列的第$i$项,那么有:$f_0=0,f_1=1;f_n=f_{n-1}+f_{n-2},n\ge2$现在有一个$n$行$m$列的数字表格,第$i$行第$j$列的数字是$f_{\gcd(i,j)}$。求这个表格所有数的乘积。共有$T$组数据,答案对$10^9+7$取模。......
  • Xcode12 开发12.5.7版本IOS的问题解决
    1.xcode12默认是创建的工程是14.2,所以需要修改一下工程版本。点击项目最上面的蓝色文件就可以打开下面的界面了。2.安装app之后,界面黑屏。解决方法如下:在AppDelegate.h中:#import<UIKit/UIKit.h>@interfaceAppDelegate:UIResponder<UIApplicationDelegate>//增......
  • [ARC143B] Counting Grids 题解
    CountingGrids题目大意将\(1\simn^2\)填入\(n\timesn\)的网格\(A\)中,对于每个格子满足以下条件之一:该列中存在大于它的数。该行中存在小于它的数。求方案数。思路分析首先有一个比较显然的结论:对于一个不合法的方案,有且仅有一个数不满足任何一个条件。考虑......
  • [ABC308G] Minimum Xor Pair Query 题解
    MinimumXorPairQuery题目大意维护一个序列,支持动态插入,删除,查询最小异或对。思路分析看到查询最小异或对首先想到01Trie,但01Trie不支持删除,考虑暴力套一个线段树分治。需要预处理出每个元素的存活区间,这里使用了map<int,vector<int>>。注意,有的元素会存活到最后,需要特......
  • 网络瘤24题解+总结
    目录网络流24题太空飞行计划最大权闭合子图模型最小路径覆盖问题Trick总结网络流24题顺序主观决定太空飞行计划教训:(开始想费用流,搞半天出不来)网络流解决最大/小费用问题,要么最小割最大流,要么最小费用流最小费用流的前提是最大流,所以在有一些点可以不取换最优代价的时候,是......
  • P5369 [PKUSC2018] 最大前缀和 题解
    传送门题目大意给定一个序列,求任意重排\(n!\)中情况所以的最大非空前缀和的和。模\(998244353\)。\(n\e20\),\(\sum|a_i|\le10^9\)题目解析考虑最大前缀和的性质,有:对于最大前缀和部分,所有的真后缀大于等于零。(最大前缀和可能小于零)对于不在最大前缀和的后半部分,所......
  • [JOI 2022 Final] 自学 题解
    洛谷传送门1.题意简述:一个学期有\(N\)天\(N*M\)节课,每天的第\(i\)节课可以选择效果\(a_i\)的学习与\(b_i\)的自习。问应如何安排每节课,使所有功课最小值最大?2.思路:这道题想直接模拟非常麻烦,但是如果我们能够灵活运用二分算法,这道题就非常简单了。考虑到数据范围较......