有些梦想虽然遥不可及,但不是不可能实现。只要我足够的强。

前言

调了挺长时间的,并查集合并的时候需要 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 分组的更多相关文章

  1. P3940 分组

    P3940 分组 https://www.luogu.org/problemnew/show/P3940 官方题解http://pan.baidu.com/s/1eSAMuXk 分析: 并查集. 首先 ...

  2. 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】

    [题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...

  3. [洛谷P3940]:分组(贪心+并查集)

    题目传送门 题目描述 小$C$在了解了她所需要的信息之后,让兔子们调整到了恰当的位置.小$C$准备给兔子们分成若干个小组来喂恰当的胡萝卜给兔子们吃.此时,$n$只兔子按一定顺序排成一排,第$i$只兔子 ...

  4. HDU 1712 ACboy needs your help(分组背包)

    题意:给你n的课程组,每个课程组有m个课程,每个课程有一个完成时间与价值.问在m天内每组课程组最多选择一个,这样可以得到的最大价值是多少 题解:分组背包,其实就是每个课程组进行01背包,再在课程组内部 ...

  5. HDU 4341 分组背包

    B - Gold miner Time Limit:2000MS      Memory Limit:32768KB     Description Homelesser likes playing ...

  6. 「NOIP2006」「LuoguP1064」 金明的预算方案(分组背包

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NNN元钱就行” ...

  7. CSP-S考前各种idea题解乱堆

    快要考试了我还是这么菜. 已经没有心思维护我的博客了.开一篇博文吧.可能会记得很乱. 这也许是我OI生涯的最后一篇博文了?? 肯定很长很长. 不可能的.谁知道什么时候我心态恢复就把上面两句话删掉开始在 ...

  8. 分组背包 例题:hdu 1712 ACboy needs your help

    分组背包需求 有N件物品,告诉你这N件物品的重量以及价值,将这些物品划分为K组,每组中的物品互相冲突,最多选一件,求解将哪些物品装入背包可使这些物品的费用综合不超过背包的容量,且价值总和最大. 解题模 ...

  9. 【洛谷P1272】 重建道路

    重建道路 题目链接 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的.因此, ...

随机推荐

  1. es6.4.0安装和配置IK+拼音插件 实现非全拼搜索

    安装IK分词器 一.进入到es的plugins文件夹创建文件夹analysis-ikmkdir analysis-ik二.下载ik压缩包文件wget https://github.com/medcl/ ...

  2. 三分钟了解B2B CRM系统的特点

    最近很多朋友想了解什么是B2B CRM系统,说到这里小Z先来给大家说说什么是B2B--B2B原本写作B to B,是Business-to-Business的缩写.正常来说就是企业与企业之间的生意往来 ...

  3. [Python] Tkinter command

    例1:创建按钮 import tkinter as tk class App: def __init__(self,root): frame = tk.Frame(root) frame.pack() ...

  4. [c++] 细节

    \r退格:printf("asdflkj\r111")输出111flkj(https://blog.csdn.net/tyshtang/article/details/436770 ...

  5. [Java] Git

    版本控制 VCS(Version Control System):版本控制系统 主要功能:版本控制.主动提交.中央仓库 中央仓库功能:保存版本历史.同步团队代码 DVCS(Distributed VC ...

  6. CENTOS7network config文件不能直接bak 必须建立bak目录再bak

    CENTOS7network config文件不能直接bak 必须建立bak目录再bak

  7. ip_conntrack or nf_conntrack : table full, dropping packet

    nf_conntrack: table full, dropping packet ip_conntrack or nf_conntrack : table full, dropping packet ...

  8. Linux学习之路-Linux-at及cron命令【7】---20171215

    Linux学习之路-Linux-at及cron命令[7]---20171215 DannyExia000人评论986人阅读2017-12-24 17:28:03   ntpdate 命令 [root@ ...

  9. SystemVerilog 编写FSM

    SystemVerilog 编写FSM 题目 SystemVerilog实现 仿真 SystemVerilog 编写FSM 好书: https://github.com/yllinux/blogPic ...

  10. django访问mysql数据库--模型(model)

    一.安装: sudo pip install mysql-connector-python sudo pip install MySQL-python 异常情况,如果提示pip超时 curl http ...