首页 > 其他分享 >CF1365G Secure Password 题解

CF1365G Secure Password 题解

时间:2024-02-17 19:45:13浏览次数:32  
标签:std 13 val int 题解 CF1365G vec Password id

Description

本题是交互题

有一个固定的数组 \(A\),同时通过数组 \(A\) 构造出数组 \(P\),具体来讲,\(P_i\) 是 \(A\) 中除 \(A_i\) 外的所有元素的按位或。

你需要在最多 \(13\) 次询问中得到最后的 \(P\) 数组。

\(2\leq n\leq 1000\)。

Solution

首先有一个 \(2\log n\) 的是注意到对于任意两个不同的数 \(i,j\),则必有至少一位满足 \(i\) 和 \(j\) 不同,所以只要维护 \(val_{i,0/1}\) 表示第 \(i\) 位为 \(0/1\) 的数的或,那么每次只要把与 \(i\) 不同的位的 \(val\) 值或起来即可。

考虑怎么优化到 \(\log n\)。

容易发现要想优化掉那个 \(2\),就必定要构造出一种方案,使得 \(id_i\) 存在一位为 \(1\),\(id_j\) 存在一位为 \(0\)。

所以只要给每个 \(i\) 分配 popcount 相同的 \(id\) 即可满足条件。

经过计算,这些 \(id\) 最小位数是 \(13\),因为 \(\binom{13}{6}>1000\)。

总询问次数:\(13\)。

Code

#include <bits/stdc++.h>

#define int int64_t

const int kMaxN = 1e3 + 5;

int n;
int id[kMaxN], val[13];

int ask(std::vector<int> vec) {
  if (!vec.size()) return 0;
  std::cout << "? " << vec.size() << ' ';
  for (auto x : vec) std::cout << x << ' ';
  std::cout << std::endl;
  int x;
  std::cin >> x;
  return x;
}

void dickdreamer() {
  std::cin >> n;
  int cnt = 0;
  for (int i = 0; i < (1 << 13); ++i) {
    if (__builtin_popcount(i) == 6) {
      id[++cnt] = i;
      if (cnt == n) break;
    }
  }
  for (int i = 0; i < 13; ++i) {
    std::vector<int> vec;
    for (int j = 1; j <= n; ++j)
      if (~id[j] >> i & 1)
        vec.emplace_back(j);
    val[i] = ask(vec);
  }
  std::cout << "! ";
  for (int i = 1; i <= n; ++i) {
    int res = 0;
    for (int j = 0; j < 13; ++j)
      if (id[i] >> j & 1)
        res |= val[j];
    std::cout << res << ' ';
  }
}

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,13,val,int,题解,CF1365G,vec,Password,id
From: https://www.cnblogs.com/Scarab/p/18018255

相关文章

  • 传纸条 题解
    题目描述小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵......
  • 2024.2.17模拟赛T1题解
    先考虑\(q=(1...n)\)的情况:发现如果设\(divcnt(p)\)表示将\(p\)划分为极小值域连续段的个数,那满足\(divcnt(p)\gem\)的排列都是合法的。那现在要求出有多少个排列符合条件可以先算出长度为\(i\),\(divnct\)为\(1\)的排列个数,这可以用dp解决然后再背包一下,就能求......
  • P2042 [NOI2005] 维护数列 题解
    题目链接:维护数列比较不好码的题,首先确保自己会一种文艺平衡树的书写,这点因人而异,比较推荐初学者学\(fhq\)平衡树,坑比较少,比较好码,写平衡树合并、持久化类的题时,也比较好写。注意到空间需求比较大,还涉及删除,我们的删除用各种树类数据结构中最常用的回收标记用于新的节点开辟。......
  • CF1929E 题解
    题意:给定一棵\(n\)个节点数和\(k\)条路径\((a_i,b_i)\),求至少将多少条边染色,使得给定路径都至少有一条染色的边。\(n\le10^5,k\le20\)。思路:好题。显然状压\(dp\),\(dp[S]\)表示至少染多少条边使得\(S\)中的路径都满足条件。正常思路是枚举子集转移,考虑\(T\s......
  • 整数划分 题解
    题目描述如何把一个正整数N(N长度<20)划分为M(M>1)个部分,使这M个部分的乘积最大。N、M从键盘输入,输出最大值及一种划分方式。输入格式第一行一个正整数T(T<=10000),表示有T组数据。接下来T行每行两个正整数N,M。输出格式对于每组数据第一行输出最大值。第二行输出划分方案,将N按......
  • 情书密码 题解
    题目描述有消息称:绝恋找到了自己的MissRight,正准备自己的表白。绝恋已经写好了情书,但为了避免其它人截获,他对情书进行加密。为了打探绝恋的私密,你冒着生命危险终于搞到了这封情书。原以为可以轻易将情书解密,结果竟然发现聪明的绝恋并没有直接写出加密用的密码,而是在那粉红色的......
  • CF484B题解
    朴素的办法是枚举每两个数然后更新取模的结果。时间复杂度为\(O(n^2)\)不能通过。这个朴素的过程可以看作枚举一个数然后找对其取模最大值的过程。我们可以枚举一个数,然后再枚举以它的倍数为两端的区间,找其中取模的最大值。找最大值的过程可以二分或双指针。值域很小,也可以......
  • 牛客小白87题解A-G
    A小苯的石子游戏本题贪心模拟即可B小苯的排序疑惑考虑到最简单的操作把n-1个数排好,最后一个看能否有序。即:a[1]<=min(a[2],a[3],a[4]..,a[n])||a[n]>=max(a[1],a[2],a[3]....,a[n-1])满足条件,反之易得不可能C&D小苯的IDE括号问题本题考察题意理解,简单版本我们可以只关注逻......
  • 0217-0224校赛部分题解
    SMUWinter2024Round#3(Div.2)对于自己比较有价值的题目是D题https://codeforces.com/gym/102897/problem/D?mobile=trueJ题https://codeforces.com/gym/102897/problem/JK题https://codeforces.com/gym/102897/problem/KE题https://codeforces.com/gym/102897/prob......
  • 关于thrift python接口和java通信出现问题解决
    真的无语,搞了一个下午。使用thrift出现错误,先说一下遇到第一个错误,如下图:那时候代码是这叼样```if__name__=='__main__':handler=MessageServiceHandler()processor=MessageService.Processor(handler)transport=TSocket.TServerSocket(None,"9090"......