题解 P3940 分组
有些梦想虽然遥不可及,但不是不可能实现。只要我足够的强。
前言
调了挺长时间的,并查集合并的时候需要 find 一下,不然会炸内存。。。。
解题思路
参考了题解区一篇思路非常好的题解,在这里讲一下自己的见解。
首先明确一下 K 的取值只有 1 或者 2 这里看数据范围非常重要!,对于 \(K=1\),\(K=2\) 的情况要分开来做。
K=1
对于 \(K=1\) 的情况,为了保证字典序最小,我们需要倒着枚举序列了。
然后再次观察数据范围,发现\(131072 \times2=512^2\),因此我们可以枚举 \(1 \sim 512\) ,令 vis[i] 表示在当前扫到的组里颜色为 i 的是否存在,查看是否访问过 \(x^2-s_i\) 。
如果访问过,表示和第 i 只兔子发生矛盾的已经在这个组里了,因此需要再次分一个组,并且记录下分组的边界,清空 vis 数组。
如果没有访问过,把该种颜色的标记成 true 记录就好了。
K=2
几乎同样的思路,我们仍然需要倒着枚举序列。
对于同一组的兔子,状态之可能有两种:同一小团体或者在敌对小团体,因此我们用并查集维护。
\(\operatorname{find}(1 \sim n)\) 表示 \(1\sim n\)的兔子所在的小团体。
\(\operatorname{find}(n+1 \sim 2 \times n)\) 表示 \(1\sim n\)的兔子所在的小团体的敌对小团体。
然后开一个 vector 数组记录同一颜色的序号,然后分别对于发生矛盾的兔子进行判断,同时更新该兔子所在组以及小团体和敌对小团体。
同样的,如果矛盾无法避免,那就重新开一个组,并清空标记,记录分割点就好了。
code
#include<bits/stdc++.h>
using namespace std;
const int M=131080;
int n,m,K,las,s[M],fa[M<<1];
vector<int> ans,v[M<<1];
bool vis[M];
int find(int x)
{
if(fa[x]==x)
return x;
return fa[x]=find(fa[x]);
}
void work_1()
{
for(int i=n;i>=1;i--)
{
bool flag=true;
for(int j=1;j<=512;j++)
if(j*j>=s[i])
if(vis[j*j-s[i]])
{
flag=false;
break;
}
if(!flag)
{
for(int j=i+1;j<las;j++)
vis[s[j]]=false;
ans.push_back(i);
las=i+1;
}
vis[s[i]]=true;
}
printf("%d\n",ans.size()+1);
for(int i=ans.size()-1;i>=0;i--)
printf("%d ",ans[i]);
}
int update(int l,int r)
{
for(int i=l+1;i<r;i++)
vector <int>().swap(v[s[i]]);
ans.push_back(l);
return l+1;
}
void work_2()
{
for(int i=1;i<=(n<<1);i++)
fa[i]=i;
for(int i=n;i>=1;i--)
{
for(int j=1;j<=512;j++)
if(j*j>=s[i])
if(v[j*j-s[i]].size())
for(int k=0;k<v[j*j-s[i]].size();k++)
{
int temp=v[j*j-s[i]][k];
if(find(temp)==find(i))
{
las=update(i,las);
break;
}
else
{
fa[find(i+n)]=find(temp);
fa[find(temp+n)]=find(i);
}
}
v[s[i]].push_back(i);
}
printf("%d\n",ans.size()+1);
for(int i=ans.size()-1;i>=0;i--)
printf("%d ",ans[i]);
}
int main()
{
scanf("%d%d",&n,&K);
las=n+1;
for(int i=1;i<=n;i++)
scanf("%d",&s[i]);
if(K==1)
work_1();
else
work_2();
return 0;
}
题解 P3940 分组的更多相关文章
- P3940 分组
P3940 分组 https://www.luogu.org/problemnew/show/P3940 官方题解http://pan.baidu.com/s/1eSAMuXk 分析: 并查集. 首先 ...
- 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】
[题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...
- [洛谷P3940]:分组(贪心+并查集)
题目传送门 题目描述 小$C$在了解了她所需要的信息之后,让兔子们调整到了恰当的位置.小$C$准备给兔子们分成若干个小组来喂恰当的胡萝卜给兔子们吃.此时,$n$只兔子按一定顺序排成一排,第$i$只兔子 ...
- HDU 1712 ACboy needs your help(分组背包)
题意:给你n的课程组,每个课程组有m个课程,每个课程有一个完成时间与价值.问在m天内每组课程组最多选择一个,这样可以得到的最大价值是多少 题解:分组背包,其实就是每个课程组进行01背包,再在课程组内部 ...
- HDU 4341 分组背包
B - Gold miner Time Limit:2000MS Memory Limit:32768KB Description Homelesser likes playing ...
- 「NOIP2006」「LuoguP1064」 金明的预算方案(分组背包
题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NNN元钱就行” ...
- CSP-S考前各种idea题解乱堆
快要考试了我还是这么菜. 已经没有心思维护我的博客了.开一篇博文吧.可能会记得很乱. 这也许是我OI生涯的最后一篇博文了?? 肯定很长很长. 不可能的.谁知道什么时候我心态恢复就把上面两句话删掉开始在 ...
- 分组背包 例题:hdu 1712 ACboy needs your help
分组背包需求 有N件物品,告诉你这N件物品的重量以及价值,将这些物品划分为K组,每组中的物品互相冲突,最多选一件,求解将哪些物品装入背包可使这些物品的费用综合不超过背包的容量,且价值总和最大. 解题模 ...
- 【洛谷P1272】 重建道路
重建道路 题目链接 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的.因此, ...
随机推荐
- 取消本地SVN文件夹与服务器的关联
方法一. 1.新建文本文档,添加内容如下: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Fold ...
- @JsonFormat 格式化时间 时出现时间不准确问题
今天突然报个问题,简单来说说就是数据库某一字段的记录时间为 14点,然而展示到前台却是 6点 我腚眼一看,postman测试的数据也是6点 然而idea查出来的并不是6点 再仔细一瞅idea实体类的时 ...
- springboot优雅的异常处理
springboot全局异常处理 @ControllerAdvice 尽管springboot会对一些异常进行处理,不过对于开发者来说,这还不太便于维护,因此我们需要自己来对异常进行统一的捕获与处理. ...
- [Java] Spring 使用
背景 JavaEE 应用框架 基于IOC和AOP的结构J2EE系统的框架 IOC(反转控制):即创建对象由以前的程序员自己new 构造方法来调用,变成了交由Spring创建对象,是Spring的基础 ...
- 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)
一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop) 概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间 ...
- 微信引流的方式 PC控制手机的方式
http://www.yunjing100.cn/ 云鲸一百 小萝卜 http://www.xiaoluobei.com/
- 2021 docker安装宝塔面板
拉取CentOS镜像 docker pull centos 创建 docker 容器 启动镜像,映射主机与容器内8888(宝塔面板).888(PHPMYADMIN)端口 -v 挂在目录 为了能够保存( ...
- 女朋友看了也懂的Kafka(上篇)
@ 目录 前言:为什么需要Kafka 1.初识kafka 1.1 消息队列的好处: 1.2 消息队列的两种模式 没有消息队列我们怎么做? 传统MQ怎么做? 这时候,Kafka就"闪亮登场&q ...
- GO学习-(32) Go实现日志收集系统1
Go实现日志收集系统1 项目背景 每个系统都有日志,当系统出现问题时,需要通过日志解决问题 当系统机器比较少时,登陆到服务器上查看即可满足 当系统机器规模巨大,登陆到机器上查看几乎不现实 当然即使是机 ...
- checkbox,select,radio 选取值,设定值,回显值
获取一组radio被选中项的值var item = $('input[@name=items][@checked]').val();获取select被选中项的文本var item = $(" ...