P14262 [ROI 2015 Day1] 自动好友

news/2025/10/20 21:06:19/文章来源:https://www.cnblogs.com/qwqSW/p/19153656

题目传送门

我的博客-欢迎光顾

写了一个很另类的容斥。。。比其他dalao的做法复杂不少


(为了方便描述,如果 \(i,j\) 是一对潜在好友,我们就称 \((i,j)\) 是一对朋友对)

(以下的 \(a,b,c\) 均指题目中的三个属性)

首先我们可以枚举两个人并判断它们能否构成一组潜在好友。时间复杂度 \(O(n^2)\)

然后,我们注意到这个题值域很小。于是本人就想着,依次算出 \(a\) 相同而 \(b,c\) 不同的朋友对, \(b\) 相同而 \(a,c\) 不同的朋友对,以及 \(c\) 相同而 \(a,b\) 不同的朋友对。最终答案就是三个朋友对的个数相加(显然不会有重复统计的朋友对)。

求这三种朋友对的方法都差不多。下面我们展开说说如何求 \(a\) 相同而 \(b,c\) 不同的朋友对。(其余同理)

我们可以将原来的人按 \(a\) 属性从小到大排序,这样 \(a\) 相同的人一定是在一个连续区间内的。

如果本题只有两个属性(仍然要求只有一个属性相同),那我们可以考虑记录一下当前 \(a\) 相同的人的左端点编号 \(l\) ,以及一个桶 \(mpb_{i}\) ,记录a属性的值落在这个区间的基础上,b属性为i的人有几个

这样,我们从左往右遍历 \(i\)\(i\) 对答案的贡献就是 \(i-l-mpb_{b_{i}}\)

现在变成三个属性了,怎么办?这个时候容斥就闪亮登场了。

沿用刚才的思路,我们用三个桶,一个桶 \(mpb_{i}\) ,记录a属性的值落在这个区间的基础上,b属性为i的人有几个;一个桶 \(mpc_{j}\) ,记录a属性的值落在这个区间的基础上,c属性为j的人有几个;一个桶 \(mp_{i,j}\) ,记录a属性的值落在这个区间的基础上,b属性为i的人且c属性为j的人有几个

这样, \(i\) 前面 \(a\) 相同但不满足条件的人的数量 \(num\) 就是 \(mpc_{c{i}}+mpb_{b{i}}-mp_{b_{i},c_{i}}\)\(i\) 对答案的贡献就是 \(i-top-num\)

这样我们就能求 \(a\) 相同而 \(b,c\) 不同的朋友对了。同理处理另两种情况即可。

代码实现的时候注意,如果进入了一个新的区间,那么 \(l\) 应当重新赋值,且 你开的几个桶都要初始化为 0 。

\(mp\) 这个桶如果不开 \(a\) 属性的这一位,那每次进入新区间都要初始化,很容易 TLE 。这里我采用了一个空间换时间的策略,给 \(mp\) 数组新开 \(a\) 的一维,这样我们只需要在处理一个大情况前初始化即可。

代码:

P14262正解
#include<bits/stdc++.h>
#define int long long
using namespace std;inline int read(){int x=0,f=1;char c=getchar();while(c<48){if(c=='-') f=-1;c=getchar();}while(c>47) x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}inline void write(int x){if(x<0) putchar('-'),x=-x;if(x<10) putchar(x+'0');else write(x/10),putchar(x%10+'0');
}const int N=1e5+5;
const int M=105;
int n,ans,mp1[M],mp2[M],mp3[M],mp[M][M][M];
//mp1,mp2,mp3:等同于题解中的mpa,mpb,mpc 
struct sw{int b[4];
}a[N];inline bool cmp1(sw x,sw y){return x.b[1]<y.b[1];
}inline bool cmp2(sw x,sw y){return x.b[2]<y.b[2];
}inline bool cmp3(sw x,sw y){return x.b[3]<y.b[3];
}inline void solve(int id){//mp桶的初始化 for(int i=1;i<=100;i++){for(int j=1;j<=100;j++){for(int k=1;k<=100;k++){mp[i][j][k]=0;}}}if(id==1){int top=0;//top:等同于题解中的l sort(a+1,a+n+1,cmp1);for(int i=1;i<=n;i++){int x=a[i].b[1],y=a[i].b[2],z=a[i].b[3];if(a[i].b[id]!=a[i-1].b[id]){//不相同则进入新区间 for(int j=1;j<=100;j++){mp2[j]=mp3[j]=0;}top=i;//记录一下左端点 }else{int x=a[i].b[1],y=a[i].b[2],z=a[i].b[3];//桶题解 int num=mp2[y]+mp3[z]-mp[x][y][z];ans=ans+(i-top-num);}//更新一下桶 mp2[y]++;mp3[z]++;mp[x][y][z]++;}}if(id==2){//注释见上 int top=0;sort(a+1,a+n+1,cmp2);for(int i=1;i<=n;i++){int x=a[i].b[1],y=a[i].b[2],z=a[i].b[3];if(a[i].b[id]!=a[i-1].b[id]){for(int j=1;j<=100;j++){mp1[j]=mp3[j]=0;}top=i;}else{int num=mp1[x]+mp3[z]-mp[x][y][z];ans=ans+(i-top-num);}mp1[x]++;mp3[z]++;mp[x][y][z]++;}}if(id==3){//注释见上 int top=0;sort(a+1,a+n+1,cmp3);for(int i=1;i<=n;i++){int x=a[i].b[1],y=a[i].b[2],z=a[i].b[3];if(a[i].b[id]!=a[i-1].b[id]){for(int j=1;j<=100;j++){mp2[j]=mp1[j]=0;}top=i;}else{int x=a[i].b[1],y=a[i].b[2],z=a[i].b[3];int num=mp2[y]+mp1[x]-mp[x][y][z];ans=ans+(i-top-num);}mp2[y]++;mp1[x]++;mp[x][y][z]++;}}
}signed main(){n=read();for(int i=1;i<=n;i++){a[i].b[1]=read(),a[i].b[2]=read(),a[i].b[3]=read();}solve(1);solve(2);solve(3);printf("%lld",ans);return 0;
}

另,如果你有对拍的需求,也欢迎你用如下代码与你的正解对拍(即 \(O(n^2)\) 代码):

P14262暴力
#include<bits/stdc++.h>
#define int long long
using namespace std;inline int read(){int x=0,f=1;char c=getchar();while(c<48){if(c=='-') f=-1;c=getchar();}while(c>47) x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}inline void write(int x){if(x<0) putchar('-'),x=-x;if(x<10) putchar(x+'0');else write(x/10),putchar(x%10+'0');
}const int N=1e5+5;
int n,a[N],b[N],c[N];signed main(){n=read();for(int i=1;i<=n;i++){a[i]=read(),b[i]=read(),c[i]=read();}int ans=0;for(int i=1;i<=n;i++){for(int j=1;j<i;j++){if((a[i]==a[j]&&b[i]!=b[j]&&c[i]!=c[j])||(a[i]!=a[j]&&b[i]==b[j]&&c[i]!=c[j])||(a[i]!=a[j]&&b[i]!=b[j]&&c[i]==c[j])){ans++;}}}printf("%lld",ans);return 0;
}

如果你觉得这篇题解还不错的话,记得留下你的赞呀qwq

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/941602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

傻瓜式处理kauditd0病毒程序记录

服务器莫名奇妙很慢,top指令查看,有个kauditd0进程导致cpu占用很高,自己或者网上尝试了各种方式,都要死灰复燃,最终打算删除启动程序的账号es,这个账号并非我正在使用发账号,直接deluser删除也会有进程占用不让…

win10 升级 win11 后时间更新失败

可能的原因:时间服务器设置问题 设置路径:设置 \(\to\) 时间和语言 \(\to\) 日期和时间 \(\to\) 更改时间服务器可选授时服务器:cn.pool.ntp.org Windows Time 服务问题 若步骤 1 同步失败,可能是 Windows Time 服…

软件工程学习日志2025.10.20

今日概览统一了全站顶部导航的视觉样式,移除各页面导航按钮的 primary 高亮,确保颜色一致与信息层级清晰。 修正了个人中心页的导航,移除指向当前页的“个人中心”按钮,避免自指链接。 启动并验证了本地服务,通过…

P14254 分割(树上计数问题) 题解

P14254 树上组合计数(分割问题)题解 原题链接 一、题目分析 这部分是解题的核心,通过分析条件得出简化问题的关键结论。计数问题先尝试找一下性质:注意到节点的选择只能越来越深 \[d_i>=d_1 \]最关键性质: \[m…

完整教程:开源 C++ QT QML 开发(一)基本介绍

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

102302104刘璇综合实践作业任务一:智能购物平台用户需求调研分析报告——基于195份问卷的用户痛点挖掘

摘要: 本报告基于《智能购物平台调查问卷数据及其可视化》收集的195份有效数据,通过科学的可视化分析方法,围绕用户基础特征、烹饪行为习惯、智能功能需求等维度展开深入研究。在两个星期的调研过程中,我从问卷设计…

软件工程第二次团队作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/202501SoftwareEngineering/这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/202501SoftwareEngineering/homework/13559这个作业的目标 使用现代 A…

Hands on Deep Learning Chapter 3 线性神经网络

3 线性神经网络 3.1 线性回归 回归(regression)、预测(prediction)、分类(classification) 3.1.1 线性回归的基本元素 线性模型:对输入特征进行一个仿射变换(affine transformation,加权和对特征进行线性变换…

超越技术范畴:低代码如何重塑企业数字文化

当我们谈论低代码时,目光往往聚焦于其提升开发效率的技术特性。然而,它的深层影响力远不止于此。低代码更像是一颗投入企业静湖的石子,其激起的涟漪,正层层扩散,深刻地重塑着组织的协作模式、创新节奏乃至内在的数…

好用的网址

填验证码(? 题解格式化。 画图。 代码格式化。 纯文字图片生成器。

【C++实战(71)】解锁C++音视频编写:FFmpeg从入门到实战

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

20251020

正睿NOIP 二十连测 A 有 \(m(m \le 95)\) 种药剂,每种药剂有 \(n_i(\sum n_i \le 10^{15})\) 瓶,等级为 \(p_i\)(\(2 \le p_i \le 499\))。要将这些药剂分成两个不相交的集合 \(X, Y\),\(X\) 的价值为其组内所有药…

低代码赋能业务创新:打破数字鸿沟,释放业务潜能

在数字化转型的浪潮中,一个突出的矛盾日益显现:业务部门汹涌的创新需求,与IT部门有限的开发资源之间,形成了一道难以逾越的“数字鸿沟”。当市场部门需要一个临时的活动报名系统,当HR部门渴望一个高效的内部推荐工…

【大模型】大模型训练的几个不同阶段

总结:各方法的典型关联(以大语言模型为例)Pre-Training:先让模型学“通识知识”(如语言、世界知识)。 Supervised Fine-Tuning (SFT):用标注数据让模型学“任务基本模式”(如指令遵循)。 Reward Modeling:训…

详细介绍:1、手把手教你入门设计半桥LLC开关电源设计,LLC谐振腔器件计算

详细介绍:1、手把手教你入门设计半桥LLC开关电源设计,LLC谐振腔器件计算pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family…

十六天

今日重点学习关系型数据库基础,核心掌握三个模块:一是数据表的结构化设计,明确字段类型(如INT、VARCHAR)需与数据属性匹配,避免后续数据存储异常;二是主键的作用,通过实操验证其“唯一标识记录”的必要性——未…

10/20/2025杂题 关于在线性时间内求解低次多项式的幂

例 设 \(g = ax^2 + bx + c\),求: \[ f = g^n\]其中 \(0 \leq n \leq 3 \times 10^5\)。结果对 \(10^9 + 7\) 取模。 首先可以直接用 MTT 在 \(O(n \log n)\) 的时间复杂度内求解。然而此做法常数太大,在需要多次求…

歌手与模特儿

https://www.luogu.com.cn/problem/AT_nikkei2019_2_final_h 第一次见到能 manacher 但不能二分+哈希的题! 直接上 manacher,当尝试将区间拓展为 \([l,r]\) 时,考察 \(nxt_l\) 和 \(lst_r\) 的位置关系,可以 check…

20251019

正睿 NOIP 十连测 B 有 \(n\) 个数 \(a_1 \sim a_n\)。初始有一个 \(x = 1\),每次需要将 \(x\) 变为某个 \(i\),花费代价为 \(\min(|i - x|, n - |i - x|)\),且 \(a_x \le a_i\)。问访问所有 \(i\) 需花费的最小代价…

计算机毕业设计 基于EChants的海洋气象数据可视化平台设计与建立 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】

计算机毕业设计 基于EChants的海洋气象数据可视化平台设计与建立 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】pre { white-space: pre !important; word-wrap: normal !important; overflo…