CF297E JZOJ 4018.【雅礼联考DAY02】Magic

2023-10-18 08:59

本文主要是介绍CF297E JZOJ 4018.【雅礼联考DAY02】Magic,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

H y p e r l i n k Hyperlink Hyperlink

https://www.luogu.com.cn/problem/CF297E


D e s c r i p t i o n Description Description

在一个园上分布着 2 n 2n 2n个点,对应 n n n条弦

请求出有多少个无序的三元组,使得对应的三条弦可以通过距离的缩放中心对称

数据范围: n ≤ 1 0 5 n\leq 10^5 n105


S o l u t i o n Solution Solution

三条弦可能的情况有下列5种

...
答案即为第二种和第五种的组合,显然用容斥可以更好得到答案

所有的组合情况共为 C n 3 C_n^3 Cn3,我们直接当做 A n s = n ( n − 1 ) ( n − 2 ) / 6 Ans=n(n-1)(n-2)/6 Ans=n(n1)(n2)/6,然后减去1、3、4三种情况即可

第一种情况比较好计算,我们只需要找到第 i i i条弦左边不与它相交的弦的数量 x i x_i xi,以及右边不与它相交的弦的数量 y i y_i yi,答案即为 x i × y i x_i\times y_i xi×yi

既然左右两边不相交的弦的数量是 x i + y i x_i+y_i xi+yi,则与 i i i相交的弦即为所有的弦出去本身( n − 1 n-1 n1)减去不想交的弦的数量,即 z i = n − 1 − ( x i + y i ) z_i=n-1-(x_i+y_i) zi=n1(xi+yi)

则第三第四种的总和即为 z i × ( x i + y i ) z_i\times(x_i+y_i) zi×(xi+yi)【相交的一个,不相交的两个】

则最终答案即为 A n s − ∑ i = 1 n ( x i y i + z i × ( x i + y i ) ) Ans-\sum_{i=1}^n (x_iy_i+z_i\times(x_i+y_i)) Ansi=1n(xiyi+zi×(xi+yi))

在算法实现中,具体的流程与上述描述的略为不同,我们不是直接求出不相交的,而是通过树状数组维护相交的弦的数量,再通过容斥计算得出

首先将所有的弦按照右端点升序排序,这样可以保证后面的弦的右端点一定在前面的弦的右端点的后边

假设我们现在要求相交的弦的数量,即 z i z_i zi,定义与它相交的弦是 j j j,有两种情况

  1. j j j左端点在 i i i的左边,且 j j j的右端点在 i i i之间
  2. j j j的左端点在 i i i之间,且 j j j的右端点在 i i i右边

T p Tp Tp(一个区间修改,单点查询的树状数组)计算所有右端点在 i i i左侧的弦【一段区间】,表示这段区间有一条弦是可以作为 j j j的端点的,如果 p [ i ] . l p[i].l p[i].l在这段区间内,那么就会有贡献,我们查询 T p . a s k ( p [ i ] . l ) Tp.ask(p[i].l) Tp.ask(p[i].l)即可,由于我们维护的是右端点在 i i i左侧的弦,所以我们要做完 i i i之后将这条线更新进去,即 T p . a d d ( p [ i ] . l , 1 ) T p . a d d ( p [ i ] . r , − 1 ) Tp.add(p[i].l,1)\ \ \ \ \ Tp.add(p[i].r,-1) Tp.add(p[i].l,1)     Tp.add(p[i].r,1)

T a Ta Ta(一个单点修改,区间查询的树状数组)计算所有的右端点在 i i i右侧的左端点,因为我们已经排了序,所以我们先放入所有的左端点,在做每一条弦之前把这条弦删掉(因为它不可能在自己的右边),这样我们就知道了右端点在 i i i的右边的左端点的分布情况(即第二种),那么我们只需要知道在 p i . l ∼ p i . r p_i.l\sim p_i.r pi.lpi.r之间有多少个合法的左端点即可,即 T a . a s k ( p [ i ] . r ) − T a . a s k ( p [ i ] . l ) Ta.ask(p[i].r)-Ta.ask(p[i].l) Ta.ask(p[i].r)Ta.ask(p[i].l)

于是我们求出了 z i z_i zi,现在考虑用它求 x i x_i xi y i y_i yi中的其中一个,就可以求出剩下那个,由于我们是按照右端点升序排序的,那么满足前面的右端点一定不会伸到后面去,所以 r r r已经在里面了,只需要找到 p [ i ] . l < p [ j ] . l < p [ i ] . r p[i].l<p[j].l<p[i].r p[i].l<p[j].l<p[i].r的【即所有左边的弦】减去所有相交的弦再除以2就可以得到 x i x_i xi

然后 y i = n − 1 − ( x i + z i ) y_i=n-1-(x_i+z_i) yi=n1(xi+zi)

直接统计即可

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)


C o d e Code Code
#include<cctype>
#include<cstdio>
#include<algorithm>
#define LL long long
#define N 100010
using namespace std;int n;
struct node{int l,r;}p[N];
LL ans,x,y,z;
inline LL read()
{char c;LL d=1,f=0;while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;return d*f;
}
inline bool cmp(node x,node y){return x.r<y.r;}
struct sszz
{LL C[N*2];inline void add(int x,int v){for(;x<=2*n;x+=x&-x) C[x]+=v;return;}inline LL ask(int x){LL T=0;for(;x;x-=x&-x)T+=C[x];return T;}
}Ta,Tp;
signed main()
{n=read();for(register int i=1;i<=n;i++){p[i].l=read();p[i].r=read();if(p[i].l>p[i].r) swap(p[i].l,p[i].r);}sort(p+1,p+1+n,cmp);ans=(long long)n*(n-1)*(n-2)/6ll;for(register int i=1;i<=n;i++) Ta.add(p[i].l,1);for(register int i=1;i<=n;i++){Ta.add(p[i].l,-1);z=Tp.ask(p[i].l)+Ta.ask(p[i].r)-Ta.ask(p[i].l);x=(p[i].r-p[i].l-1-z)/2;y=n-1-x-z;ans-=x*y+z*(x+y)/2;Tp.add(p[i].l,1);Tp.add(p[i].r,-1);}                printf("%lld",ans);
}

这篇关于CF297E JZOJ 4018.【雅礼联考DAY02】Magic的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/231551

相关文章

javaweb-day02-2(00:40:06 XML 解析 - Dom4j解析开发包)

导入dom4j开发包:dom4j-1.6.1.jar   在工程下建一个文件夹lib,将dom4j-1.6.1.jar拷到里边。右键add to build path。  dom4j-1.6.1\lib文件夹下还有一些jar包,是开发过程中dom4j所需要依赖的jar包,如开发过程中报错,则需导入。   用dom4j怎么做呢? 只要是开源jar包提供给你的时候,它会在开源包里面提供

javaweb-day02-2(XML 解析 - Jaxp的sax方式解析)

Jaxp解析开发包 Sax解析方式只能做查询: Sax解析方式和DOM解析方式的区别:     在使用 DOM 解析 XML 文档时,需要读取整个 XML文档,在内存中构架代表整个DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。  SAX解析允许在读取文档的时候,即对文档进行处

Qlik数据集成 | Qlik 连续 14 年稳居 2024 Gartner® ABI Magic Quadrant™ 领导者

Qlik 再次当选 2024 年 Gartner® 分析和商业智能平台 Magic Quadrant™ 领导者! 近日,作为引领当今数据集成、数据质量和分析解决方案市场的行业领导者, Qlik 再次当选 2024 年 Gartner® 分析和商业智能平台 Magic Quadrant™ 领导者! 得益于 Qlik 在愿景完备性和执行能力方面的出色表现,这已经是 Qlik 第 14 年位居领导者象

网络编程day02(字节序、TCP编程)

目录 【1】字节序 1》大小端转换 2》端口转换   3》IP地址转换 主机字节序转换为网络字节序 (小端序->大端序) 网络字节序转换为主机字节序(大端序->小端序)  【2】TCP编程 1》流程 2》函数接口 1> socket 2> bind 3> listen 4> accept  5> recv  6> connect 7> send  3》代码展示

最值求解 | 管理类联考数学专项

日期内容2024.9.5新建2024.9.6曦曦求最值完结 实数求最值至少至多抽屉原理工程问题线性规划一次性绝对值求最值 参考: b站跟着曦曦老师玩转【最值】

笔试强训day02

牛牛的快递 import matha,b = input().split()a = float(a)price = 20if a>1:price += math.ceil(a)-1if b=='y':price += 5print(price) 最小花费爬楼梯 #include <bits/stdc++.h>const int N = 1e5+10;int co

Magic推出100M个token的上下文

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行! 订阅:https://rengongzhineng.io/ 目前,AI模型有两种学习方式:一种是通过训练,另一种是在推理过程中通

Jzoj 条件循环(while,do while) 部分代码(共25题)

1020: 【入门】编程求1+3+5+...+n #include <bits/stdc++.h>using namespace std;int n, sum;int main() {scanf("%d", &n);for(int i=1; i<=n; i+=2){sum+=i;} printf("%d", sum);return 0;} 1012: 【入门】两数比大小 #i

Jzoj 二维数组部分代码(共13题)

2788: 【入门】二维数组的输入输出 边输入边输出 #include <bits/stdc++.h>using namespace std;int n, m, a[11][11];int main(){scanf("%d %d", &n, &m);//边输入边输出for(int i=1; i<=n; ++i){for(int j=1; j<=m; ++j){scanf("%d", &

蓝桥杯备赛day02:递推

斐波那契数列 #include <bits/stdc++.h>using namespace std;int main(){int n;cin>>n;int dp[n+1];dp[1]=1;dp[2]=1;for(int i = 3;i <= n;i++) dp[i] = dp[i-1]+dp[i-2];cout<<dp[n];return 0;} n = int(input())