ABC371 Review

news/2025/1/15 13:49:03/文章来源:https://www.cnblogs.com/Hanggoash/p/18415335

ABC371 Review

A

分类讨论题 ,过

B

模拟题,过

C

题意

给出一张原始图 \(G\) ,和一张待修改图 \(H\) ,每次对 \(H\) 进行一次操作可以花费相应的代价删除已经存在的一条边或者是添加未存在的边。

问使得两张图同构的最小代价 \(W\) 是多少。

思路

以为是什么高级的算法,但是又放在了 C 这个位置,又觉得是什么高深的结论,最后还是没有做出来。

其实注意到了 \(N\) 的值非常的小,考虑过暴力 dfs ,想了想好像不知道该怎么判断选出来的图是否和原图同构,于是就放弃开 D 题去了。

D

题意

给出 \(n\) 个二元组 \((x_i,p_i)\) ,其中 \(x_i\in[-10^9,10^9],p_i\in [0,10^9]\) 。有 \(m<2\times 10^5\) 个询问 ,每个询问给出一个 \([l,r]\) ,求出 \(\sum_i^{x_i\in[l,r]} p_i\) 的值。

思路

暴力跳显然是会超时的,然后数组的下标会出现负数,所以很自然的会想到离散化后再前缀和。

但是大可不必这么做,由于树状数组的复杂度是 \(\log n\) 的,所以完全可以直接前缀和。

这里不用开数组,直接用 unordered_map 代替数组就可以了,注意分左右两边统计。

Code

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=3e5;
template<typename T>inline void re(T &x)
{x=0;int f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x*=f;
}
template<typename T>inline void wr(T x)
{if(x<0)putchar('-'),x=-x;if(x>9)wr(x/10);putchar(x%10^48);
}
int n;
int maxr=-1,minl=1e9+7;
unordered_map<int,int> c1,c2;
inline int lowbit(int x){return x&(-x);}
inline void add1(int x,int v)
{for(;x<=1e9;x+=lowbit(x))	c1[x]+=v;
}
inline int query1(int x)
{int ans=0;for(;x>=1;x-=lowbit(x))ans+=c1[x];return ans;
}
inline void add2(int x,int v)
{for(;x<=1e9;x+=lowbit(x))	c2[x]+=v;
}
inline int query2(int x)
{int ans=0;for(;x>=1;x-=lowbit(x))ans+=c2[x];return ans;
}
int x[N],p[N];
int ans0;
inline void pre()
{re(n);for(register int i=1;i<=n;++i)re(x[i]),maxr=max(maxr,x[i]),minl=min(minl,x[i]);minl=-minl;for(register int i=1;i<=n;++i){re(p[i]);if(x[i]>0)add1(x[i],p[i]);else if(x[i]<0) add2(-x[i],p[i]);else ans0=p[i];}
}
signed main()
{pre();int t;re(t);while(t--){int l,r;re(l),re(r);if(l<0){if(r<0)wr(query2(-l)-query2(-r-1));else if (r==0)wr(query2(-l)+ans0);else wr(query2(-l)+ans0+query1(r));}else if(l==0){if(r==0)wr(ans0);else wr(ans0+query1(r));}else{wr(query1(r)-query1(l-1));	}putchar('\n');}return 0;
}

E

题意

给定序列 \({a_N}\) ,定义 \(f(l,r)\)\([l,r]\) 区间内不同数字的种类数,求 \(\sum_{i=1}^n\sum_{j=i}^n f(i,j)\)

\(n\le2\times 10^5\)

思路

很显然,哪怕是我们能够去 \(O(n^2)\) 地统计 ,\(O(1)\) 地枚举,也是会超时的。

分开来考虑每个区间的贡献,如果一个区间包含 \(x\) ,不论个数,那么它就会对答案产生 \(1\) 的贡献。

这时候我们可以考虑转而枚举 \(x\) ,考虑在 \([1,n]\) 的范围内有多少个包含它的区间 ,那么就是 \(x\) 这个数对答案的贡献 $ans(x) $ 。

最后的答案就是 \(\sum_{x=1}^Nans(x)\)

进一步的,对于每一个 \(ans(x)\) ,都可以通过补集思想求出 ,也就是 \(ans(x)=C_{n}^2-\sum (\text{invalid})\),这一步可以在读入的时候就求出。

具体的,我们可以通过记录每一个数上一个出现的位置 \(las_{a[i]}\) ,那么对于 \(x\) 来说不合法的方案数就是 \([las_{a[i]}+1,i-1]\),注意最后要在 \(n+1\) 这个位置上面再对所有出现过的数字再用相同的方法统计一次。

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6;
template<typename T>inline void re(T &x)
{x=0;int f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x*=f;
}
template<typename T>inline void wr(T x)
{if(x<0)putchar('-'),x=-x;if(x>9)wr(x/10);putchar(x%10^48);
}
inline int c(int i){return i*(i-1)/2+i;}
int n,a[N],las[N];
int tmp;
signed main()
{cin>>n;int ans=0;int cnt=0;for(int i=1;i<=n;++i){re(a[i]);if(!las[a[i]])cnt++;tmp+=c(i-las[a[i]]-1);las[a[i]]=i;}for(int i=1;i<=n;++i){if(!las[i])continue;tmp+=c(n-las[i]);}wr(cnt*(c(n))-tmp);
//	cout<<endl;
//	for(int i=1;i<=n;++i)return 0;
}

延伸

对于去统计区间内不同数的种类,这道题是属于比较特殊的一种,因为会把全部的区间都给枚举完,所以我们可以从数学的角度来快速统计答案。但是如果现在不对所有区间进行询问,而是给出 \(q\)\([l,r]\) 的询问,又该如何处理呢?

很容易想到莫队等一系列区间算法,加上树状数组求逆序对的启发,大可以搞一个权值树状数组的算法,题目链接如下 :

P1972 HH的项链

这道题会单独写一篇题解。

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

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

相关文章

计算机执行汇编代码的原理

计算机执行汇编代码的原理 汇编语言(Assembly Language)是一种低级编程语言,它与机器语言(Machine Language)密切相关。汇编语言由人类可读的指令构成,这些指令会被转化为机器可以理解的二进制代码,即机器码。本文将介绍计算机如何执行汇编代码的基本原理,并通过图文说…

MySQL 大表拆分

概述 在实际工作中,在关系数据库(MySQL、PostgreSQL)的单表数据量上亿后,往往会出现查询和分析变慢甚至无法执行统计分析的情况。这时就需要将大表拆分为多个小表,将小表分布在多个数据库上,形成一个数据库集群。这样的话,一条 SQL 统计语句就可以在多台服务器上并发执行…

条件编译 - 代码裁剪的工具 --进阶C语言

目录条件编译 - 代码裁剪的工具为何要有条件编译条件编译都在那些地方用?见一见条件编译的代码宏是否被定义 vs 宏是否为真or假编译器也能够自动帮你加上宏GCCVS2023-VS2019#ifdef/#ifndef#if注意事项让#if和#ifdef/#ifndef完全一样条件编译也支持嵌套一个使用#if defined能起…

这些年没来得及学习的一些 HTML5 标签

认识并学习下还没来得及学习的一些 HTML5 标签 <ruby> 标签 HTML <ruby> 元素被用来展示东亚文字注音或字符注释。 比如: <ruby>兄弟<rt>xiongdi</rt></ruby><rt> 元素包含字符的发音,字符在 ruby 注解中出现,它用于描述东亚字符的…

软件工程第二次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13253这个作业的目标 变大变强学号 102201542项目名称:e了个mo github作业仓库链接:(https://github.com/zqh666nb/e-mo) !!!运行ma…

win11 nimi主机安装软路由

硬件 带两个LAN口的mini主机 软件 win11家庭版 openwrt一 安装hyper-v虚拟机 由于是win11家庭版,启用或关闭 Windows 功能里没有hyper-v win11家庭版启用Hyper-V的方法 创建脚本pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.…

帝国cms认证码怎么取消

取消帝国CMS中的认证码(也称为验证码),可以通过以下几种方法来实现: 1. 通过后台设置取消 如果你只是想在某些特定的操作中取消认证码,比如在会员注册、登录或后台管理时不需要验证码,可以尝试通过后台设置来取消:登录后台:登录帝国CMS的后台管理系统。进入系统设置:在…

dedecms修改文档标题最大长度

在DedeCMS中修改文档标题的最大长度可以通过以下几种方法实现: 方法一:通过后台设置登录后台:登录到DedeCMS的后台管理系统。进入系统设置:在后台管理界面,找到“系统”->“系统基本参数”。修改文档标题长度:在“系统基本参数”设置中,找到“其他选项”->“文档标…

织梦在导航栏下拉菜单中怎么调用当前栏目子类

在织梦CMS (DEDECMS) 中,要在导航栏的下拉菜单中调用当前栏目的子类,可以使用channelartlist标签来实现。下面是如何实现这一功能的具体步骤: 步骤 1: 使用channelartlist标签 在织梦CMS中,可以利用channelartlist标签来调用当前栏目的子类。下面是一个示例代码:<ul>…

帝国cms怎么上传图片

在帝国CMS中上传图片可以通过多种方式实现,具体取决于你是想在文章中插入图片还是批量上传图片到服务器。下面是两种常见的上传图片的方法: 1. 在文章编辑时上传图片 当你在撰写或编辑文章时,可以直接上传图片并插入到文章内容中:登录后台:登录帝国CMS的后台管理系统。进入…

c#委托事件订阅模型

namespace WinFormsApp2 {delegate void ShowName(object sender);//声明委托类型,委托类型可以理解为一类方法的类型 ,如此处的showbuttonname方法便是符合showName类型public partial class Form1 : Form{private event ShowName btnclick; //声明事件,此处相当于实例…

织梦cms调取栏目高亮特殊样式的限制字节方法

在织梦CMS中,如果你想要调取栏目并且为当前访问的栏目添加高亮显示效果,同时限制字节数,可以采用以下方法: 方法一:使用runphp 如果你熟悉PHP编程,可以通过在模板中使用runphp标签来实现这一功能。不过需要注意的是,runphp标签的使用可能会带来一定的安全隐患,因为它允…