2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
全场比赛题解:https://pan.baidu.com/s/1eSAMuXk
刚看这题觉得很难,于是数据点分治
k只有1和2两种,分别讨论:
- k=1:根据人类直觉,不难想到一种贪心策略:从前往后扫,若扫到的数能加入当前这段就加入,否则再开一段新的。
于是你就WA了...
题目要求字典序最小,而我们的策略会让当前段尽可能长,所以划分点会靠后。例如:1 2 3 4 5,可以分为{1},{2,3,4},{5}三段,而我们的策略得到的答案为{1,2},{3,4},{5}。
类似《菜肴制作》那道题,既然正向贪心不对,考虑反向贪心。
可以从后往前扫描,仍按贪心策略,可以保证后面的段尽量长,即划分点尽量靠左。官方题解证明了这种策略的正确性。
现在我们的问题是如何快速判定一个数能不能加入当前段落,即对于一个数b,判断当前段是否存在一个数a,满足\(a+b=x^2\)。发现\(\sqrt{2*\max(a_i)}\)只有520左右,可以每次枚举x,判断\(x^2-b\)是否存在。
复杂度\(O(n\sqrt n)\) - k=2:仍可以按上述策略从后往前扫,每次相当于判断当前段加入一个数之后能否划分为两个集合,使每个集合内任意两数之和都不是完全平方数。类似《魔术球》那道题,就是二分图判定。二分图判定用染色法复杂度较高,可以用边带权/扩展域并查集判定二分图(类似《关押罪犯》)。
根据k=1的做法,我们还是想到按数值合并,但这时会出现一种特殊情况:当序列为2、7时,2和7可以划分在两个集合中;但当序列中出现两个2,这两个2需要划分在不同集合,再出现一个7就不能划分在这两个集合中了。所以扫描的时候需要特判。
这里并查集只写了路径压缩,没有按秩合并,所以复杂度多了个log。
Code:
#include <bits/stdc++.h>
using namespace std;
const int N=131075;
int table[600]={0,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484,529,576,625,676,729,784,841,900,961,1024,1089,1156,1225,1296,1369,1444,1521,1600,1681,1764,1849,1936,2025,2116,2209,2304,2401,2500,2601,2704,2809,2916,3025,3136,3249,3364,3481,3600,3721,3844,3969,4096,4225,4356,4489,4624,4761,4900,5041,5184,5329,5476,5625,5776,5929,6084,6241,6400,6561,6724,6889,7056,7225,7396,7569,7744,7921,8100,8281,8464,8649,8836,9025,9216,9409,9604,9801,10000,10201,10404,10609,10816,11025,11236,11449,11664,11881,12100,12321,12544,12769,12996,13225,13456,13689,13924,14161,14400,14641,14884,15129,15376,15625,15876,16129,16384,16641,16900,17161,17424,17689,17956,18225,18496,18769,19044,19321,19600,19881,20164,20449,20736,21025,21316,21609,21904,22201,22500,22801,23104,23409,23716,24025,24336,24649,24964,25281,25600,25921,26244,26569,26896,27225,27556,27889,28224,28561,28900,29241,29584,29929,30276,30625,30976,31329,31684,32041,32400,32761,33124,33489,33856,34225,34596,34969,35344,35721,36100,36481,36864,37249,37636,38025,38416,38809,39204,39601,40000,40401,40804,41209,41616,42025,42436,42849,43264,43681,44100,44521,44944,45369,45796,46225,46656,47089,47524,47961,48400,48841,49284,49729,50176,50625,51076,51529,51984,52441,52900,53361,53824,54289,54756,55225,55696,56169,56644,57121,57600,58081,58564,59049,59536,60025,60516,61009,61504,62001,62500,63001,63504,64009,64516,65025,65536,66049,66564,67081,67600,68121,68644,69169,69696,70225,70756,71289,71824,72361,72900,73441,73984,74529,75076,75625,76176,76729,77284,77841,78400,78961,79524,80089,80656,81225,81796,82369,82944,83521,84100,84681,85264,85849,86436,87025,87616,88209,88804,89401,90000,90601,91204,91809,92416,93025,93636,94249,94864,95481,96100,96721,97344,97969,98596,99225,99856,100489,101124,101761,102400,103041,103684,104329,104976,105625,106276,106929,107584,108241,108900,109561,110224,110889,111556,112225,112896,113569,114244,114921,115600,116281,116964,117649,118336,119025,119716,120409,121104,121801,122500,123201,123904,124609,125316,126025,126736,127449,128164,128881,129600,130321,131044,131769,132496,133225,133956,134689,135424,136161,136900,137641,138384,139129,139876,140625,141376,142129,142884,143641,144400,145161,145924,146689,147456,148225,148996,149769,150544,151321,152100,152881,153664,154449,155236,156025,156816,157609,158404,159201,160000,160801,161604,162409,163216,164025,164836,165649,166464,167281,168100,168921,169744,170569,171396,172225,173056,173889,174724,175561,176400,177241,178084,178929,179776,180625,181476,182329,183184,184041,184900,185761,186624,187489,188356,189225,190096,190969,191844,192721,193600,194481,195364,196249,197136,198025,198916,199809,200704,201601,202500,203401,204304,205209,206116,207025,207936,208849,209764,210681,211600,212521,213444,214369,215296,216225,217156,218089,219024,219961,220900,221841,222784,223729,224676,225625,226576,227529,228484,229441,230400,231361,232324,233289,234256,235225,236196,237169,238144,239121,240100,241081,242064,243049,244036,245025,246016,247009,248004,249001,250000,251001,252004,253009,254016,255025,256036,257049,258064,259081,260100,261121,262144,263169,264196,265225,266256,267289,268324,269361,270400};
int n,k,mx,tot,ans[N],a[N];
bool vis[N],dvis[N],issqu[3*N];
void In(int &num){
register char c=getchar();
for(num=0;!isdigit(c);c=getchar());
for(;isdigit(c);num=num*10+c-48,c=getchar());
}
namespace solve1{
inline bool check(int num){//判断num能否加入当前段
for(int i=1;i<=520;++i){
if(table[i]<=num) continue;
if(table[i]-num>mx) break;
if(vis[table[i]-num]) return true;
}
return false;
}
void solve(){
for(int i=n,last=n;i>=2;--i){
vis[a[i]]=true;
mx=max(mx,a[i]);
if(check(a[i-1])){//a[i-1]不能加入当前段
mx=0;
for(int j=last;j>=i;--j) vis[a[j]]=false;//清空数组
ans[++tot]=i-1;//新开一段
last=i-1;
}
}
}
}
namespace solve2{
int fa[3*N];
int Find(int x){
return fa[x]==x?x:fa[x]=Find(fa[x]);
}
bool check(int u,int v){//u和v已经冲突 判断它们能否分到不同集合
int t1=Find(u),t2=Find(u+N);
int s1=Find(v),s2=Find(v+N);
if(t1==s1||t2==s2) return false;
fa[t1]=s2;fa[t2]=s1;
return true;
}
void solve(){
for(int i=1;i*i<=2*N;++i) issqu[i*i]=true;
for(int i=1;i<=2*N;++i) fa[i]=i;
for(int i=n,last=n;i;--i){
if(vis[a[i]]){//出现过
if(issqu[2*a[i]]){
if(dvis[a[i]]) goto fail;//已经出现过两次
for(int j=1;j<=520;++j){
if(table[j]<=a[i]) continue;
if(table[j]-a[i]>mx) break;
if(vis[table[j]-a[i]]&&table[j]!=2*a[i]) goto fail;
}
dvis[a[i]]=true;//标记第二次出现
}
}
else{//没出现过
for(int j=1;j<=520;++j){
if(table[j]<=a[i]) continue;
if(table[j]-a[i]>mx) break;
if(vis[table[j]-a[i]]&&(dvis[table[j]-a[i]]||(!check(a[i],table[j]-a[i])))) goto fail;
}
vis[a[i]]=true;
}
mx=max(mx,a[i]);
continue;
fail:
mx=a[i];
ans[++tot]=i;
for(int j=last;j>=i+1;--j) fa[a[j]]=a[j],fa[a[j]+N]=a[j]+N,vis[a[j]]=dvis[a[j]]=false;
fa[a[i]]=a[i],fa[a[i]+N]=a[i]+N;vis[a[i]]=true;//注意这里 当前段的右端点是i 需要重新标记
last=i;
}
}
}
int main(){
In(n);In(k);
for(int i=1;i<=n;++i) In(a[i]);
if(k==1) solve1::solve();
else solve2::solve();
printf("%d\n",tot+1);
for(int i=tot;i;--i) printf("%d ",ans[i]);
putchar('\n');
return 0;
}
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组的更多相关文章
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】
[题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...
- 20190803 NOIP模拟测试12「斐波那契(fibonacci)· 数颜色 · 分组 」
164分 rank11/64 这次考的不算太差,但是并没有多大的可能性反超(只比一小部分人高十几分而已),时间分配还是不均,T2两个半小时,T1半个小时,T3-额十几分钟吧 然额付出总是与回报成反比的 ...
- NOIP模拟测试12
T1 斐波那契 一道找规律题,被我做成了贼难的题. 观察图片可知x=f[i-1]+j.(j为x的父亲)且j<=f[i-1],然后就二分找父亲没了. #include<bits/stdc++ ...
- [NOIP模拟测试12]题解
A. 找规律题.儿子的编号减去 小于它编号的最大的fibonacci数 即可得到它父亲的编号. 然后两个节点都暴力上跳就好了.预处理一下fibonacci数,每次二分查找即可. #include< ...
- 2019.8.1 NOIP模拟测试11 反思总结
延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- NOIP模拟测试17&18
NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...
随机推荐
- 关于apache kylin 安装32位linux办法
最近公司在使用apache kylin做实时开发访问,但是自己集群是linux32 只能安装JDK32位的受限只能3G多内存,而apachekylin 默认是4G内存,需要JDK64位支持. 解决办法 ...
- 用sqoop抽取oracle 表到hbase的例子
sqoop import \-Doraoop.disabled=true \--connect jdbc:oracle:thin:@"(DESCRIPTION=(ADDRESS=(PROTO ...
- Java 8 的新特性和Java 的4种引用方式
一.接口的增强 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,示例如下: interface Formula { double ca ...
- UVa-401 Palindromes回文词
虽然是水题,但是容易错.参照了紫书的代码可以写的很简洁.主要还是注意常量数组的使用,能让代码变得简单许多 #include <iostream> #include <cstdio&g ...
- View的滑动冲突和解决方案
1.滑动冲突原因: 当有内外两层View同时可以滑动的时候,这个时候就会产生滑动冲突. 2.常见的冲突场景: 场景1: 场景2: 场景3: 4.解决方法种类: (1)外部拦截法: 针对场景1,我们可以 ...
- Git的基本了解与使用、向github提交代码
#Git的基本了解与使用.向github提交代码- git:是一个版本控制系统.- github:一个代码托管提供商.开源网站.是一个面向开源及私有软件项目的托管平台,因为支持Git作为唯一的版本库格 ...
- jmeter的组件介绍--框架
测试计划(test plan):用于存放测试脚本的容器. 线程(threads):通过java多线程来实现模拟多用户操作,只有在线程组下才能添加sample(各种协议的请求),因此线程是必须的. 取样 ...
- ubuntu setup.py 安装时报Error -5 while decompressing data: incomplete or truncated stream
缺少 python-devel 包 apt-get install python-dev -y
- 开户项目的sql查询语句备查
查询全国所有的券商名录 SELECT id,security,province,city,borough FROM t_security GROUP BY security ; 查询某个省份的所有券商 ...
- MySQL笔记<一>创建数据库和表
参考博客 https://www.cnblogs.com/sqbk/p/5806797.html https://www.cnblogs.com/tomasman/p/7151962.html