首先一定要从每个数的范围 \(i - n \le a_i \le i - 1\) 入手,最开始是这样一个想法,不难发现对于每个 \(i\) 都能选 \(n\) 个数,并且能选的右端点在 \(i - 1\),那么我们可以吧每个 \(i\) 前移一位,实际上就是 \(0 \sim n - 1\) 这些位置上选没选数,而如果这个位置上没选那么就一定选在了前面,实际上这样还是非常不好做,于是我考虑只选择了一个负数的情况,发现还是不能发现一种简便的方法来找出这个集合,因此我们需要换一种方式思考。

既然分析性质行不通,我们可以考虑直接构造出答案。像这种找到一个集合满足一些条件的题目,我们可以将其转化为图论问题,例如求一个连通块的权值和为特定值或者找到一个环使得环上权值和为特定值,转化方式就需要巧妙的连边了。因为 \(a_i\) 涉及到负数不方便连边,于是我们可以对于每个 \(a_i\) 增添一个增量 \(k\),即将 \(a_i \rightarrow b_i = a_i + k_i\) 那么原问题就转化为寻找一个集合使得 \(\sum b_i = \sum k_i\)。我的想法是对于每个 \(i\) 我们连边 \(i \rightarrow a_i + k_i\) 可以发现这中间有 \(n\) 条边,因为是有向边我们找联通块不方便,因此可以考虑找环。于是我们接下来的目的就是寻找一个合适的 \(k_i\) 使得连出来环上的边满足上述条件,然后我就不会做了,下面的做法只能无限 \(\rm stO\) 出题人。首先我们需要注意到这样一件事,如果刚好 \(n\) 个点,\(n\) 条边那么图中一定会存在一个环,于是我们就可以让 \(1 \le a_i + k_i \le n\) 那么这样就一定会出现环了,与此同时我们需要注意到一个如果要满足 \(\sum b_i = \sum k_i\) 那么不难发现环上的权值和要是编号和,事实上根据之前的连边如果能出现环那么环上的权值和一定是编号和,因为我们是每个编号 \(i\) 向外连一条边。再观察一下数据范围 \(i - n \le a_i \le i - 1\),两边不正好出现了 \(1, n\) 吗?先把两边减去 \(i\) 可得 \(-n \le a_i - i \le -1\) 再反个号 \(1 \le i - a_i \le n\) 不就是我们想要的东西吗?于是对于每个 \(i\) 我们连边 \(i \rightarrow i - a_i\) 再在图上找一个环即可。注意多组数据不能直接 \(\rm memset\)。

#include<bits/stdc++.h>
using namespace std;
#define N 1000000 + 5
#define rep(i, l, r) for(int i = l; i <= r; ++i)
bool book[N];
int T, n, x, top, cnt, a[N], fa[N], st[N], ans[N];
int read(){
char c; int x = 0, f = 1;
c = getchar();
while(c > '9' || c < '0'){ if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int main(){
T = read();
while(T--){
n = read();
rep(i, 1, n) a[i] = read(), fa[i] = i - a[i];
x = 1, cnt = top = 0;
while(!book[x]) book[x] = true, st[++top] = x, x = fa[x];
while(st[top] != x) book[st[top]] = false, ans[++cnt] = st[top--];
ans[++cnt] = st[top];
while(top) book[st[top--]] = false;
printf("%d\n", cnt);
rep(i, 1, cnt) printf("%d ", ans[i]); puts("");
}
return 0;
}

CF1270G Subset with Zero Sum的更多相关文章

  1. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  2. 动态规划法(三)子集和问题(Subset sum problem)

      继续讲故事~~   上次讲到我们的主人公丁丁,用神奇的动态规划法解决了杂货店老板的两个找零钱问题,得到了老板的肯定.之后,他就决心去大城市闯荡了,看一看外面更大的世界.   这天,丁丁刚回到家,他 ...

  3. 698. Partition to K Equal Sum Subsets

    Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...

  4. CF1249F Maximum Weight Subset

    CF1249F Maximum Weight Subset 洛谷评测传送门 题目描述 You are given a tree, which consists of nn vertices. Reca ...

  5. codeforces 360 E - The Values You Can Make

    E - The Values You Can Make Description Pari wants to buy an expensive chocolate from Arya. She has  ...

  6. E - The Values You Can Make

    E - The Values You Can Make Description Pari wants to buy an expensive chocolate from Arya. She has ...

  7. C - NP-Hard Problem

    C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:262144 ...

  8. CF687C. The Values You Can Make[背包DP]

    C. The Values You Can Make time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  9. Codeforces Round #360 (Div. 2) E. The Values You Can Make DP

    E. The Values You Can Make     Pari wants to buy an expensive chocolate from Arya. She has n coins, ...

随机推荐

  1. MySQL8.0的下载与安装

    下载 进入官网的下载页面 点击下图中的链接 可以选择上边的 Community Server ,那样会下载压缩包,这里我选择下边的 Installer for Windows ,下载的是安装包 点击下 ...

  2. Linux 离奇磁盘爆满解决办法

    问题原因&通用解决步骤 频繁收到es数据节点磁盘使用监控告警,到es上查看,磁盘使用率40%,因此登录该告警服务器,df -h 查看,如图 发下根目录使用超过了80%,因此持续告警,按照以往办 ...

  3. 关于java的Excel导入导出之easypoi

    导入easypoi相关jar包,这里的easypoi-base的包也可以不倒入,因为easypoi-web中有依赖easypoi-base会自动导入的 <!-- https://mvnrepos ...

  4. APP自动化,怎样让应用不重置?

    noReset =True产生的背景: 在编写APP自动化代码时,除了登录用例需要填写账号和密码外,其余很多用例都是需要先登录再操作的,如果每一个用例都从头开始到具体的操作,这样将会耗费很多时间,此时 ...

  5. 简单的sdn防火墙

    github仓库 演示视频 本次实验建立的拓扑 使用到的 pox 指令介绍,参考pox控制器学习笔记 1. forwarding.l2_learning 使OpenFlow交换机充当L2学习交换机的一 ...

  6. Spark案例练习-打包提交

    关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新)云盘目录说明:tools目录是安装包res 目录是每一个课件对应的代码和资源等doc 目录是一 ...

  7. vue 使用mock来模拟数据

    首先,需要安装mock npm install mockjs --save-dev 在main.js中引入mock mock文件写法如下: const Mock = require('mockjs') ...

  8. .NET对接极光消息推送

    什么是APP消息推送? 很多手机APP会不定时的给用户推送消息,例如一些新闻APP会给用户推送用户可能感兴趣的新闻,或者APP有更新了,会给用户推送是否选择更新的消息等等,这就是所谓的"消息 ...

  9. SYCOJ#1077、01字符串

    题目-01字符串 (shiyancang.cn) 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main() 5 { 6 ...

  10. 使用 SourceGenerator 简化 Options 绑定

    目录 摘要 Options 绑定 使用 SourceGenerator 简化 如何 Debug SourceGenerator 如何 Format 生成的代码 使用方法 SourceCode & ...