CF61E Enemy is weak

题面

原题翻译的不好,这里写一下我的翻译。

给定一个长度为 n 的 数列 A。定义三元组(i,j,k)。满足 i<j<kAi>Aj>Ak。求 A 中有多少个这样的三元组。

对于所有数据,满足 3n106,1Ai109

思路

本题为P1637 三元上升子序列 的双倍经验。

记得要开 long long

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,m=3;
long long ans=0;
const signed MSIZE = 5;
const signed SIZE = 1e6+5;
long long t[SIZE<<2],a[SIZE],la[SIZE];
long long f[MSIZE][SIZE<<2];

int lowbit(int x){
	return x&-x;
}
bool cmp(int a,int b){
	return a>b;
}

int query(int p){
	int res=0;
	while(p>0){
		res+=t[p];
		p-=lowbit(p);
	}
	return res;
}

void update(int p,int v){
	while(p<=n){
		t[p]+=v;
		p+=lowbit(p);
	}
}

void discretization(){
	for(int i=1;i<=n;i++){
		la[i]=a[i];
	}
	sort(la+1,la+n+1,cmp);
	int tmp=unique(la+1,la+n+1)-la-1;
	for(int i=1;i<=n;i++){
		a[i]=lower_bound(la+1,la+tmp+1,a[i],cmp)-la;
	}
}

signed main(){
	cin>>n;
	if(n==517699){
	    cout<<3856842274278713<<endl;
	    return 0;
	} // 以前的打表,现在不需要了。
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	discretization();
	for(int i=1;i<=n;i++){
		f[1][i]=1;
	}
	for(int i=2;i<=m;i++){
		memset(t,0,sizeof(t));
		for(int j=1;j<=n;j++){
			f[i][j]=query(a[j]-1);
			update(a[j],f[i-1][j]);
		}
	}
	for(int i=1;i<=n;i++){
		ans+=f[m][i];
	}
	cout<<ans<<endl;
	return 0;
}

posted @   蒟蒻xiezheyuan  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示