CH - 0502 七夕祭(思维+中位数优化+前缀和优化)
题目链接:点击查看
题目大意:七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。于是TYVJ今年举办了一次线下七夕祭。Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩。
TYVJ七夕祭和11区的夏祭的形式很像。矩形的祭典会场由N排M列共计N×M个摊点组成。虽然摊点种类繁多,不过cl只对其中的一部分摊点感兴趣,比如章鱼烧、苹果糖、棉花糖、射的屋……什么的。Vani预先联系了七夕祭的负责人zhq,希望能够通过恰当地布置会场,使得各行中cl感兴趣的摊点数一样多,并且各列中cl感兴趣的摊点数也一样多。
不过zhq告诉Vani,摊点已经随意布置完毕了,如果想满足cl的要求,唯一的调整方式就是交换两个相邻的摊点。两个摊点相邻,当且仅当他们处在同一行或者同一列的相邻位置上。由于zhq率领的TYVJ开发小组成功地扭曲了空间,每一行或每一列的第一个位置和最后一个位置也算作相邻。现在Vani想知道他的两个要求最多能满足多少个。在此前提下,至少需要交换多少次摊点。
题目分析:中文题目,题意不难理解,首先我们应该知道,行和列是两个独立的个体,在交换相邻两行的时候,对列是没有贡献的,同理,在交换相邻两列的时候,对行也是没有贡献的,所以我们只针对于交换相邻两列的情况讨论:
首先列数一共有m列,摊数一共有t个,若t%m不为0,那么对于列是无解的,如果有解的话,那么每一列最后都需要有t/m个摊点才行,而相邻两个可以交换,我们先假设当前的模型不是环状的而是线状的,a[1]是开头,a[m]是结尾,这样一来就能线性递推出答案了,比如:
- 若a[i]>t/m,则a[i]需要给a[i+1] a[i]-t/m个摊点
- 若a[i]<t/m,则a[i+1]需要给a[i] t/m-a[i]个摊点
用上面的关系就能线性递推出答案了
但实际上题目并不是这么简单的,题目将线性的模型改成了环状的模型,也就是说必定存在着一种最优解,能让答案最小,换句话说,必定有两个相邻的列之间没有发生摊位的交换,就像上面提到的线性模型一样,开头节点和末尾节点之间就没有发生摊位的交换,在这种情况下求最优解,我们最朴素的方法是枚举每一个断点,一共需要枚举n次,每次都需要进行O(n)的递推,才能计算出答案,从而维护出最小值,总的时间复杂度为n*n+m*m,这个题目给出的n和m都达到了1e5的级别,所以n*n肯定会超时的,我们需要想办法优化
我们可以一开始就让a[i]数组的每一项都减去t/m,最后结果为正说明需要往后面扔,为负说明需要从后面拿,这样我们维护一个前缀和sum[i],第i项对答案的贡献就是abs(sum[i])了,其实思想和上面的方法类似,只不过上面的思想相当于模拟整个过程,而这里的思想是将模型抽象出来,转换为数学公式而已了,比如第i个位置的贡献是a[i],先不管他的正负,我们都需要将a[i]先转移(拿走或提供)给a[i+1],然后再计算a[i+1]的贡献,随后再将a[i+1]的贡献转移给a[i+2],如此往复就是一个前缀和了,并且当前前缀和的最后一项一定等于0,即sum[m]=0
但上述转换只是换了种方法求每个位置对答案的贡献,实质上时间复杂度还是O(n),并没有起到优化的作用,所以我们需要继续转换,到这里我们发现对于求答案,也只能优化为O(n)了,实在是没有办法再优化了,那么我们就只能着手于优化另一个O(n),也就是枚举n个端点选出最小值的过程了
因为有了前缀和sum[i]的辅助,我们可以设置某个断点k,此时第k+1个点充当第一个点,第k个点充当最后一个点,这样我们将刚才求得的前缀和稍加转换:
第几项 前缀和
a[k+1] sum[k+1]-sum[k]
a[k+2] sum[k+2]-sum[k]
....
a[m] sum[m]-sum[k]
a[1] sum[1]+sum[m]-sum[k]
....
a[k] sum[k]+sum[m]-sum[k]
这样我们在知道断点的下标后,就可以O(1)求出所需要的前缀和了,也就不需要每次再用O(m)重新维护前缀和了
因为我们在上面提到过,sum[m]=0,那么上面的每一项都可以总结为一个通项了,对于第i项,他的前缀和就是sum[i]-sum[k],那么当前位置对答案的贡献也就是abs(sum[i]-sum[k]),我们现在只要找到k,使得i=[1,m]的贡献和最小就可以了,上面我们最朴素的方法是暴力枚举,线性维护最小值,但被我们直接驳回了,我们通过观察以及总结可以得出结论,若想让上面的式子贡献和最小,让sum[k]选取sum数组的中位数即可,这样我们只需要对sum数组排序,时间复杂度为nlogn,忽略其余常数的话,这个题目的额时间复杂度就优化为nlogn+mlogm了,完美解决
不得不提一句,这个题目和“货仓选址”那个题目又有点不同,货仓选址那个题目也是让在数轴上选取一个位置,使得abs(a[i]-x)的贡献和最小,可以得出的结论是:
- 当n为奇数时,货仓建在a[n/2+1]处最优
- 若n为偶数时,货仓建在a[n/2]~a[n/2+1]之间(闭区间)的任何位置都是最优解
所以在做这个题目的时候,我直接按照分类讨论,当n为奇数时,求得的中位数是(a[n/2]~a[n/2+1])/2,但只得了90分,最后一拍脑瓜才知道,货仓选址这个题目的中位数是可以在数轴上任意选取的,但这个题目的中位数是只能再sum数组中选取,所以如果除以2的话,求出来的答案可能不是sum数组中的元素,所以求出来的答案就不满足题意了
那么对于这个题目,我们也无需分奇偶讨论了,统统以sum[(n+1)/2]作为中位数就可以了
还有一个细节需要注意,就是前缀和和最终答案可能会爆int,记得开longlong就好了
代码:
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;int n,m,t;LL ans_r,ans_c;struct Pos
{int x,y;
}a[N];LL c[N];bool solve_r()//处理行
{if(t%n)return false;memset(c,0,sizeof(c));for(int i=1;i<=t;i++)//记录每一列有多少个摊位c[a[i].x]++;for(int i=1;i<=n;i++)//维护前缀和c[i]=c[i]-t/n+c[i-1];sort(c+1,c+1+n);//排序LL temp=c[(n+1)/2];//中位数ans_r=0;for(int i=1;i<=n;i++)//计算贡献和ans_r+=llabs(c[i]-temp);return true;
}bool solve_c()//处理列,同上
{if(t%m)return false;memset(c,0,sizeof(c));for(int i=1;i<=t;i++)c[a[i].y]++;for(int i=1;i<=m;i++)c[i]=c[i]-t/m+c[i-1];sort(c+1,c+1+m);LL temp=c[(m+1)/2];ans_c=0;for(int i=1;i<=m;i++)ans_c+=llabs(c[i]-temp);return true;
}int main()
{
// freopen("input.txt","r",stdin);
// ios::sync_with_stdio(false);scanf("%d%d%d",&n,&m,&t);for(int i=1;i<=t;i++)scanf("%d%d",&a[i].x,&a[i].y);bool flag_c=solve_c();bool flag_r=solve_r();if(flag_c&&flag_r)printf("both %lld\n",ans_c+ans_r);else if(flag_c)printf("column %lld\n",ans_c);else if(flag_r)printf("row %lld\n",ans_r);elseprintf("impossible\n");return 0;
}
CH - 0502 七夕祭(思维+中位数优化+前缀和优化)相关推荐
- BZOJ3032 七夕祭 均分纸牌问题的变式 (前缀和+中位数)
题目: 背景 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是JoyOI今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去JoyOI七夕祭游玩. 描述 ...
- acwing 105 七夕祭 中位数 + 前缀和 贪心
七夕节因牛郎织女的传说而被扣上了「情人节」的帽子. 于是TYVJ今年举办了一次线下七夕祭. Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. TYVJ七夕祭和11 ...
- 中位数应用-货仓选址-纸牌均分-糖果传递-七夕祭
1. 货仓选址 描述 在一条数轴上有N家商店,它们的坐标分别为 A[1]~A[N].现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品.为了提高效率,求把货仓建在何处,可以使得货 ...
- 中位数--《算法竞赛进阶指南》(货仓选址和七夕祭问题详解)
中位数 今天又和大家见面了啦~ 依旧是 <算法竞赛进阶指南>的学习哦~ 中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本.种群或概 ...
- AcWing 七夕祭
AcWing 七夕祭 Description 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子. 于是TYVJ今年举办了一次线下七夕祭. Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决 ...
- 【NOIP2013模拟】七夕祭
题目描述 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. TYVJ七夕祭 ...
- 七夕祭( Poetize系列)
Description 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. ...
- 《算法竞赛进阶指南》0x05 T3 七夕祭
题目描述 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子. 于是 TYVJ 今年举办了一次线下七夕祭. Vani 同学今年成功邀请到了 cl 同学陪他来共度七夕,于是他们决定去 TYVJ 七夕祭游玩 ...
- 【周末狂欢赛7】【NOIP模拟赛】七夕祭,齿轮(dfs),天才黑客
文章目录 T1 题目 题解 code T2 题目 题解 code T3 题目 题解 code T1 题目 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Van ...
最新文章
- swoole UDP TCP客户端
- CephFS管理命令
- Windows 10 系统版本更新历史
- textarea标签内容为(英文或数字不自动换行)的解决方法
- 仿某某网站模板thinkphp_西安网站建设到底是什么?
- JavaScript条形码生成插件 - 封装篇
- bzoj 1070: [SCOI2007]修车【最小费用最大流】
- 机器学习-吴恩达-笔记-6-应用机器学习的建议
- Quartz的使用案例
- two sample ttest paired ttst
- R语言:KNN算法的实现——kknn包
- C#实现邮箱发送的多种方式
- 用服务器建立个人网站
- 图像增强及直方图均衡化在图像去雾上的应用(附matlab代码)
- 【node.js】nvm安装最新教程
- python学习笔记爬虫——爬取智联招聘信息
- sap进阶系列(16):第一篇:财务总览之全面预算管理
- uniapp打包h5_全局可视化装修商城上线,可打包APP
- node使用express+multer文件上传和下载的问题
- mysql jstorm_jstorm进阶-ack机制及KafkaSpout