首页 > 其他分享 >1236. 递增三元组

1236. 递增三元组

时间:2022-10-04 19:14:27浏览次数:57  
标签:1236 int mid 递增 cnt 三元组 ++ include scanf

https://www.acwing.com/problem/content/1238/
先用桶装有数的
for(int i=1;i<=n;i++) cnt[a[i]]++;
cnt[i]表示前i个数有数的,有就为1,无就为0
再利用递推计算一下前缀和s[i]
s[i]=cnt[0]+cnt[1]+cnt[2]+....+cnt[i]
则有
for(int i=1;i<N;i++)s[i]=s[i-1]+cnt[i];
由于数都是用桶装的,即每一个有数的cnt[i]都是1
则前缀和s[i]即表示有数的个数,或者是说,比i小的数或者等于i的数出现的个数

我们需要算的是有多少中组合方式,则对于一个特定的B[j],A值和C值互不影响
可相乘求组合数

接下来就是枚举B[i],求在B值为B[i]下,小于B[i]的A值可以有多少种,大于B[i]的C值可以为多少种
相乘后,把所有此值求和即可

小于B[i]的A值的个数,由此前求的前缀和得,为 s[ b[i]-1 ] 
大于B[i]的C值的个数,稍加分析,可知由减法运算可算出,即为 s[ N-1 ]-s[ b[i] ]
上述两式对应的是同一个B[i],所以我们需要枚举B[i],相乘求和
可以用数组存储单独枚举每一个B[i],小于B[i]的A值的个数;
即若as[N]表示A中小于B[i]的个数;
那么既有as[i]=s[ b[i]-1 ] ;
同理有cs[i]=s[ N-1 ]-s[ b[i] ];

存储后,再在后面共同枚举B[j],计算as[i]*cs[i]求和即可

#include<iostream>
#include<cstring>
#include<algorithm>
#define N 100010
using namespace std;
typedef long long LL;
int n;
int a[N],b[N],c[N];
int as[N];
int cs[N];
int cnt[N],s[N];//模拟
int main()
{
    cin>>n;
    for(int i = 0;i < n;i ++)   scanf("%d",&a[i]),a[i]++;//加1是为了后面处理as不越界,都加了1,就不影响结果个数
    for(int i = 0;i < n;i ++)   scanf("%d",&b[i]),b[i]++;
    for(int i = 0;i < n;i ++)   scanf("%d",&c[i]),c[i]++;
    for(int i = 0;i < n;i ++)   cnt[a[i]] ++;
    for(int i = 1;i < N;i ++)   s[i] = s[i-1] + cnt[i];
    for(int i = 0;i < n;i ++)   as[i] = s[b[i] - 1];//
    memset(cnt,0,sizeof cnt);
    memset(s,0,sizeof s);
    for(int i = 0;i < n;i ++)   cnt[c[i]] ++;
    for(int i = 1;i < N;i ++)   s[i] = s[i-1] + cnt[i];//最大可以枚举到C[N-1]
    for(int i = 0;i < n;i ++)   cs[i] = s[N-1] - s[b[i]];
    LL res = 0;
    for(int i = 0;i < n;i ++)   res += (LL)as[i]*cs[i];
    cout<<res<<endl;
    return 0;
}

 显然,此题也具有二段性
枚举每一个B[i],不断二分逼近满足a[i]>b[i]
同理,不断二分逼近满足c[i]<b[i];
记录他们的下标,再进行乘法原理计算
可以用排序+二分做法

#include<iostream>
#include<cstring>
#include<algorithm>
#define N 100010
using namespace std;
typedef long long LL;
int n;
int a[N], b[N], c[N];
LL res;
int main()
{
	cin >> n;
	for (int i = 0; i < n; i ++) scanf("%d", &a[i]), a[i]++;
	for (int i = 0; i < n; i ++) scanf("%d", &b[i]), b[i]++;
	for (int i = 0; i < n; i ++) scanf("%d", &c[i]), c[i]++;
	sort(a, a + n);
	sort(b, b + n);
	sort(c, c + n);
	for (int i = 0; i < n; i++)
	{
		int l = 0, r = n - 1;
		while (l < r)
		{
			int mid = l + r + 1 >> 1;
			if (a[mid] < b[i])l = mid;
			else r = mid - 1;
		}
		if (a[l] >= b[i]) //a中无小小于b[i]的数
			l = -1; //做个标记
		int flag1 = l; //未做标记则flag1为正确答案
		l = 0, r = n - 1;
		while (l < r)
		{
			int mid = l + r >> 1;
			if (c[mid] > b[i])r = mid;
			else l = mid + 1;
		}
		if (c[l] <= b[i]) //c中无大于b[i]的数
			r = n;
		int flag2 = r;
		res += (LL)(flag1 + 1) * (n - flag2);
	}
	cout << res << endl;
	return 0;
}

 

标签:1236,int,mid,递增,cnt,三元组,++,include,scanf
From: https://www.cnblogs.com/lxl-233/p/16754233.html

相关文章

  • 【code基础】判断数组中每个元素前递增序列子序列的最大长度
    这是力扣刷题中很经典的一个套路,类似有:以下标i为标准,其之前最长的非递增序列的个数以下标i为标准,其之后的最长非递减序列的个数//以下标i为标准,其之前最长的非递增......
  • 力扣-491-递增子序列
    起因是我做笔试,要写出所有子序列并做条件判断,我以为是回溯改一改,但事实上完全不是这样的直达链接主要是1,利用二进制序列枚举快速生成所有的可能子序列,然后利用哈希算法对......
  • 动态规划之最长递增子序列
    给你一个整数数组nums,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1......
  • 单链表的递增排序
    voiesort(LinkList&L){LNode*p=L->next;LNode*pre;LNode*r=p->next;p->next=NULL;p=r;while(p!=NULL){r=p......
  • 最长递增子段
    ★实验任务YZF有一个序列A,由n个整数组成。我们将子段A称为Ai、Ai+1、Ai+2、…Aj(1<=i<=j=n)表示A的子段。你的任务是找到A的最长的子段,这样就可以从子段最多......
  • 在递增的链表中删除min到max之间的所有元素
    在递增的链表中删除min到max之间的所有元素存在一个递增的链表,其中相邻两个结点的数据域的值要么相等,要么就是后面的大于前面的,对该表进行删除值属于(min,max)包括min和m......
  • LeetCode 491 递增子序列
    classSolution{public:vector<vector<int>>res;vector<int>path;intnum=-101;voiddfs(intstart,vector<int>&nums){if(pat......
  • leetcode 674 最长连续递增序列 C/C++ 动态规划,动态规划空间优化,双指针 三种解法,初识
    #if 0class Solution {  //动态规划public:    int findLengthOfLCIS(vector<int>& nums) {        vector<int> dp(nums.size());     ......
  • 递增/递减操作符的一些事儿
    intnumber=41;number++;cout<<number;像number++这样的表达式会返回值,可以使用如下表达式2*(number++);假设number初始值为2,那么上面表达式的输出为4,虽然递......
  • LeetCode/递增的三元子序列
    给你一个整数数组nums,判断这个数组中是否存在长度为3的递增子序列1.贪心法贪心更新两个最左端端点classSolution{public:boolincreasingTriplet(vector<int>......