2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

全场比赛题解:https://pan.baidu.com/s/1eSAMuXk

刚看这题觉得很难,于是数据点分治

k只有1和2两种,分别讨论:

  1. 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)\)
  2. 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. 分组的更多相关文章

  1. 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色

    2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...

  2. 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)

    2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

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

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

  4. 20190803 NOIP模拟测试12「斐波那契(fibonacci)· 数颜色 · 分组 」

    164分 rank11/64 这次考的不算太差,但是并没有多大的可能性反超(只比一小部分人高十几分而已),时间分配还是不均,T2两个半小时,T1半个小时,T3-额十几分钟吧 然额付出总是与回报成反比的 ...

  5. NOIP模拟测试12

    T1 斐波那契 一道找规律题,被我做成了贼难的题. 观察图片可知x=f[i-1]+j.(j为x的父亲)且j<=f[i-1],然后就二分找父亲没了. #include<bits/stdc++ ...

  6. [NOIP模拟测试12]题解

    A. 找规律题.儿子的编号减去 小于它编号的最大的fibonacci数 即可得到它父亲的编号. 然后两个节点都暴力上跳就好了.预处理一下fibonacci数,每次二分查找即可. #include< ...

  7. 2019.8.1 NOIP模拟测试11 反思总结

    延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...

  8. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  9. NOIP模拟测试17&18

    NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...

随机推荐

  1. 通过java反射实现的excel数据导出

    Excel.java @SuppressWarnings("deprecation") public static <T> void ExportExcel(Strin ...

  2. storm-jdbc的使用

    最近项目组分配到研究storm-jdbc用法 发现网上关于insert和query方法挺多的,但是自定义方法很少.而且用法上也挺多缺陷.在此自己总结记录一下 JdbcInsertBolt 的核心代码 ...

  3. win10上的vs2015项目到win7的2015无法使用

  4. Luogu P2051 [AHOI2009]中国象棋(dp)

    P2051 [AHOI2009]中国象棋 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个 \(N\) 行 \(M\) 列的棋盘上,让你放若干个炮(可以是 \(0\) 个),使得没有一个炮 ...

  5. AppServer初始化渠道

    1.写了一个拦截器(RequestInterceptor) 2.里边有个有一个doRequest()方法 3.初始化渠道的方法(initRequestContext()) -------------- ...

  6. BZOJ 4554: [Tjoi2016&Heoi2016]游戏

    Time Limit: 20 Sec Memory Limit: 128 MB Submit: 951 Solved: 572 [Submit][Status][Discuss] Descriptio ...

  7. zoj2562 反素数

    /* 这题1 <= n <= 1016,暴力肯定是TLM,所以看了大牛求解小于N的反素数的算法,思路大致是这样的: 性质1:一个反素数的质因子一定是从2开始的若干个连续质数. 因此可以枚举 ...

  8. grpc安装

    整个过程就是: 1.客户端 发送 数据(以字节流的方式) 2.服务端接收,并解析. 根据 约定 知道要知道执行什么.然后把结果返回客户端 RPC就是 把 1.上述过程封装下,使其操作更加优化 2.使用 ...

  9. WPF 利用HwndSource拦截Windows消息

    WPF提供了一个HwndSource可以使你更快的实现处理Windows消息. 通过HwndSource.FromHwnd得到的HwndSource可以添加(AddHook)移除(Remove)Hoo ...

  10. hql 条件查询 返回空的一种情况

    为何会出现查询为空,但是查询整个表没问题的情况呢? 这里是没有分清字符串和变量 原来写的是, String hql = "from ClientInfoModel where clientI ...