首页 > 其他分享 >【题解】B - 三元上升子序列

【题解】B - 三元上升子序列

时间:2024-10-04 17:00:16浏览次数:7  
标签:int 题解 thair lt 序列 三元 数据结构 ri define

目录

题目内容

Description

Erwin 最近对一种叫thair的东西巨感兴趣。。。
在含有 \(n\) 个整数的序列\(a_1,a_2,\ldots,a_n\) 中,三个数被称作thair当且仅当 \(i\lt j\lt k\) 且 \(a_i\lt a_j\lt a_k\)。
求一个序列中 thair 的个数。

Input

开始一行一个正整数 \(n\),
以后一行 \(n\) 个整数 \(a_1,a_2,\ldots,a_n\)。

Output

一行一个整数表示thair的个数。

数据规模与约定

  • 对于 \(30\%\) 的数据 保证 \(n\le100\);
  • 对于 \(60\%\) 的数据 保证 \(n\le2000\);
  • 对于 \(100\%\) 的数据 保证 \(1\le n\le3\times10^4\),\(1\le a_i\le 10^5\)。

思路

我们可以通过统计以 \(a_i\) 开头的、以 \(a_i\) 结尾的、以 \(a_i\) 作为中间点的thair个数来统计答案。而在这三种方法里,无疑是最后一种最好实现。对于一个 \(a_i\),我们只需要统计满足 \(j<i\And a_j<a_i\) 的 \(j\) 的个数 \(k_1\),满足 \(j>i\And a_j>a_i\) 的 \(j\) 的个数 \(k_2\),相乘即可得到 \(a_i\) 对于答案的贡献。对于每个 \(a_i\),分开算它们的 \(k_1\) 和 \(k_2\)。
这里以算 \(k_1\) 为例来介绍实现步骤。从前往后遍历,每到一个位置就把这个值加入一个支持单点修改、查询前缀和的数据结构,数据结构开在值域上,加数就把对应位置的值 \(+1\),找答案就直接查询前缀和即可。由于 \(j\) 严格小于 \(i\) 所以要先统计在把当前位置的数加入数据结构(当然,由于 \(a_j\) 严格小于 \(a_i\),所以不注意顺序也无所谓)。\(k_2\) 同理。
至于使用的数据结构,可以是树状数组、线段树或值域分块(好像还有CDQ分治)。这里给出值域分块的解法,复杂度 \(O(n\sqrt{n})\)。其余算法的复杂度为 \(O(n\log n)\)。

代码

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define inf 0x3f3f3f3f
int a,b[30003],c[30003];
long long ans;
struct Block_Array//块状数组封装
{
	#define N 100001
	#define M 404
	int cnt,len,lt[M],rt[M],num[M],col[N],be[N];
	il void build(int x)//分块
	{
		len=sqrt(x);
		cnt=x/len;
		fill(col+1,col+1+x,0);
		fill(num+1,num+1+cnt,0);
		for(ri i=1;i<=cnt;i++)
		{
			lt[i]=rt[i-1]+1;
			rt[i]=rt[i-1]+len;
		}
		if(rt[cnt]!=x)
		{
			cnt++;
			lt[cnt]=rt[cnt-1]+1;
			rt[cnt]=x;
		}
		for(ri i=1;i<=cnt;i++)
		{
			for(ri j=lt[i];j<=rt[i];j++)
			{
				be[j]=i;
			}
		}
	}
	il void clear(int x)//为了省时间所以反向之前清空存值数组而不是重新分块
	{
		fill(col+1,col+1+x,0);
		fill(num+1,num+1+cnt,0);
	}
	il void add(int x)//加值
	{
		col[x]++;
		num[be[x]]++;
	}
	il int find(int x,int y)//区间和查询
	{
		if(x>y)
		{
			return 0;
		}
		ri rn=0;
		if(be[x]==be[y])
		{
			for(ri i=x;i<=y;i++)
			{
				rn+=col[i];
			}
		}
		else
		{
			for(ri i=x;i<=rt[be[x]];i++)
			{
				rn+=col[i];
			}
			for(ri i=be[x]+1;i<=be[y]-1;i++)
			{
				rn+=num[i];
			}
			for(ri i=lt[be[y]];i<=y;i++)
			{
				rn+=col[i];
			}
		}
		return rn;
	}
	#undef N
	#undef M
}ba;
int main()
{
	scanf("%d",&a);
	ba.build(100000);
	for(ri i=1;i<=a;i++)
	{
		scanf("%d",&b[i]);
		c[i]=ba.find(1,b[i]-1);
		ba.add(b[i]);
	}
	ba.clear(100000);
	for(ri i=a;i>=1;i--)
	{
		ans+=c[i]*ba.find(b[i]+1,100000);
		ba.add(b[i]);
	}
	printf("%lld",ans);
	return 0;
}
/*
4
2 1 3 4

2

5
1 2 2 3 4

7
*/

标签:int,题解,thair,lt,序列,三元,数据结构,ri,define
From: https://www.cnblogs.com/ywhhdjser-97/p/18446682

相关文章

  • BUUCTF_MISC题解析(3,4)
    3.你竟然赶我走搜索010editor官网,点第一个页面,下载010editor(十六进制编译器)(黄色图标),直接010editor打开(或者使用stegSolve)一般情况用ctrl+f进入字符串搜索查看是否有插入的flag信息,就可以在文件尾看到flag是flag{stego_is_s0_bor1ing} 4.二维码扫码识别二维码,发现隐......
  • 【题解】Solution Set - NOIP2024集训Day42 博弈论
    【题解】SolutionSet-NOIP2024集训Day42博弈论https://www.becoder.com.cn/contest/5574https://www.cnblogs.com/CloudWings/p/17813917.html「中山市选2009」谁能赢呢?一道经典的「二分图博弈」在棋盘问题上的应用。https://www.luogu.com.cn/article/h8a79k3i......
  • [题解](更新中)MX-X6 A~B
    Portal:https://www.luogu.com.cn/contest/200833A-もしも容易发现可以构造\(1,x\)或\(x,1\)让序列如\(\dots,1,x,1,x,1,x,\dots\)这样循环。只需要关注\(n\)的奇偶性即可。点击查看代码#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;intt,n,an;si......
  • java 反序列化 cc6 复现
    复现环境:common-collections版本<=3.2.1,java版本随意.我们观察java高于8u71的版本会发现sun.reflect.annotation.AnnotationInvocationHandler类被进行了修改,其中的readObject不去调用setvalue方法,而是创建了一个LinkedHashMapvar7去重新进行操作,使我们之前的利用链中断.p......
  • Leetcode 1498. 满足条件的子序列数目
    1.题目基本信息1.1.题目描述给你一个整数数组nums和一个整数target。请你统计并返回nums中能满足其最小元素与最大元素的和小于或等于target的非空子序列的数目。由于答案可能很大,请将结果对109+7取余后返回。1.2.题目地址https://leetcode.cn/problems/num......
  • [题解]SFMOI Round I A~C
    Portal:https://www.luogu.com.cn/contest/179008\(\bf{100+50+50+25+5=\color{indianred}225\color{black}\,\rk.\184}\)A-StrangeCakeGame显然对于小W,向下移动蛋糕刀是最有利的;对于小M,向右移动是最有利的。所以双方以最佳状态移动,最终\(x\ley\)的巧克力是小W的。直接......
  • 【题解】「CF765F」Souvenirs
    https://www.luogu.com.cn/problem/CF765F首先有一个比较navie的\(O(n\sqrtm\logn)\)的做法(add和del的时候,用两个multiset维护一下。有一个bitset的做法来优化用multiset查询前驱后继的做法:https://www.luogu.com.cn/article/zcmco6hd首先考虑离线下来,将询问挂......
  • CF154C题解
    传送门:https://codeforces.com/problemset/problem/154/C求出无向图中,满足所有出边都相连或出边直接连接点对的点对数。很显然可以暴力枚举点对一对对去check,时间复杂度\(O(n^2+m)\)。#include<bits/stdc++.h>usingnamespacestd;inlineintread(){charc;boo......
  • 构树 题解
    构树题解好题,除了毒瘤卡空间。“恰好”这个形式很二项式反演。设\(f(n)\)表示树上钦定\(n\)条边和原树相同的方案数,\(g(n)\)表示树上恰好有\(n\)条边和原树相同的方案数,那么原先的形式是:\[f(n)=\sum_{i\gen}{i\choosen}g(i)\]二项式反演得到:\[g(n)=\sum_{i\gen}(......
  • QOJ 8726 [APIO2024] 魔术表演 题解
    DescriptionAlice和Bob是著名的魔术师。Catherine是一位富豪,她非常喜欢观看Alice和Bob的魔术。某一天,Catherine决定向Alice和Bob发出挑战:只要他们能成功表演如下的魔术,Catherine就将向他们提供巨额奖金!这个魔术的表演过程如下:步骤\(1\):Bob进⼊⼀个密室中,在魔术......