AtCoder Beginner Contest 439 - D - Kadomatsu Subsequence

Time Limit: 2 sec / Memory Limit: 1024 MiB

Score : 425 points

Problem Statement

You are given an integer sequence A=(,,...,) of length N.

Find the number of triples of integers (i,j,k) that satisfy all of the following:

  • 1≤i,j,k≤N
  • ::=7:5:3
  • min(i,j,k)=j or max(i,j,k)=j.

Constraints

  • All input values are integers.
  • 1≤N≤
  • 1≤Ai≤

Input

The input is given from Standard Input in the following format:

复制代码
N
​  … 

Output

Output the answer.


Sample Input 1

cpp 复制代码
10
3 10 7 10 7 6 7 6 5 14

Sample Output 1

复制代码
7

The seven triples of integers (i,j,k) that satisfy the conditions are:

  • (3,9,1)
    • ::=7:5:3, and max(i,j,k)=j.
  • (5,9,1)
    • ::=7:5:3, and max(i,j,k)=j.
  • (7,9,1)
    • ::=7:5:3, and max(i,j,k)=j.
  • (10,2,6)
    • ::=14:10:6=7:5:3, and min(i,j,k)=j.
  • (10,2,8)
    • ::=14:10:6=7:5:3, and min(i,j,k)=j.
  • (10,4,6)
    • ::=14:10:6=7:5:3, and min(i,j,k)=j.
  • (10,4,8)
    • ::=14:10:6=7:5:3, and min(i,j,k)=j.

Sample Input 2

cpp 复制代码
6
210 210 210 210 210 210

Sample Output 2

复制代码
0

Sample Input 3

cpp 复制代码
21
49 30 50 21 35 15 21 70 35 9 50 70 21 49 30 50 70 15 9 21 30

Sample Output 3

复制代码
34

考察点

1.数据统计与哈希映射

需要统计每个值在序列中的出现位置,由于值域很大(1≤Ai​≤),但序列长度有限(1≤N≤),使用哈希表将每个值映射到其索引列表是高效的选择。

cpp 复制代码
unordered_map<int,vector<int>>pos;
for(int i=0;i<n;i++){
    cin>>a[i];
    pos[a[i]].push_back(i+1);
}

2.条件转化与枚举优化

比例条件 ​::​=7:5:3 转化为 存在正整数t,使得​=7t、=5t、​=3t。

通过枚举中间值5t(即)来减少枚举量:只需检查每个是5的倍数的值,计算对应的7t和3t是否存在于序列中。

cpp 复制代码
for(int j=1;j<=n;j++){
    int val=a[j-1];
    if(val%5)continue;
    int t=val/5;
    int val3=t*3,val7=t*7;

    /****************************/

}

3.索引条件处理

条件 min(i,j,k)=j 或 max(i,j,k)=j 意味着 j 必须是三个索引中最小值或最大值。

这转化为对于每个候选的 j(对应值5t),分别计算:

当j最小时:统计值7t的索引中大于j的数量,以及值3t的索引中大于j的数量,两者乘积即为贡献。

当j最大时:统计值7t的索引中小于j的数量,以及值3t的索引中小于j的数量,两者乘积即为贡献。

4.二分查找加速

由于索引列表有序,对于每个j,需要在另外两个值的索引列表中快速查询大于或小于j的元素个数。使用二分查找可以将每次查询的复杂度降至O(log n),确保整体效率。

cpp 复制代码
vector<int>&pos3=pos[val3];
vector<int>&pos7=pos[val7];

//情况一:max(i,j,k)=j
auto p3=lower_bound(pos3.begin(),pos3.end(),j);
auto p7=lower_bound(pos7.begin(),pos7.end(),j);
ll c=p3-pos3.begin(),d=p7-pos7.begin();
ans+=c*d;

//情况2:min(i,j,k)=j
p3=upper_bound(pos3.begin(),pos3.end(),j);
p7=upper_bound(pos7.begin(),pos7.end(),j);
c=pos3.end()-p3,d=pos7.end()-p7;
ans+=c*d;

5.复杂度控制

整体算法的时间复杂度为O(N log N),适合1≤N≤。关键在于避免暴力枚举三元组,而是通过枚举中间值、利用哈希表和二分查找来高效计数。


代码

(要点已注释)

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;
    cin>>n;
    vector<int>a(n);
    unordered_map<int,vector<int>>pos;
    for(int i=0;i<n;i++){
        cin>>a[i];
        pos[a[i]].push_back(i+1);
    }
    ll ans=0;//长整型防止溢出
    for(int j=1;j<=n;j++){
        int val=a[j-1];
        if(val%5)continue;
        int t=val/5;
        int val3=t*3,val7=t*7;

        vector<int>&pos3=pos[val3];//注意:是引用,而不是拷贝(vector<int>pos3=pos[val3],会超时)
        vector<int>&pos7=pos[val7];

        //情况一:max(i,j,k)=j
        auto p3=lower_bound(pos3.begin(),pos3.end(),j);
        auto p7=lower_bound(pos7.begin(),pos7.end(),j);
        ll c=p3-pos3.begin(),d=p7-pos7.begin();
        ans+=c*d;

        //情况2:min(i,j,k)=j
        p3=upper_bound(pos3.begin(),pos3.end(),j);
        p7=upper_bound(pos7.begin(),pos7.end(),j);
        c=pos3.end()-p3,d=pos7.end()-p7;
        ans+=c*d;
    }
    cout<<ans;
    return 0;
}
相关推荐
无极低码2 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发2 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
Thera7773 小时前
C++ 高性能时间轮定时器:从单例设计到 Linux timerfd 深度优化
linux·开发语言·c++
superior tigre3 小时前
22 括号生成
算法·深度优先
君义_noip4 小时前
信息学奥赛一本通 1952:【10NOIP普及组】三国游戏 | 洛谷 P1199 [NOIP 2010 普及组] 三国游戏
c++·信息学奥赛·csp-s
努力也学不会java4 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
旖-旎4 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针
ECT-OS-JiuHuaShan5 小时前
朱梁万有递归元定理,重构《易经》
算法·重构
顶点多余5 小时前
使用C/C++语言链接Mysql详解
数据库·c++·mysql
汉克老师5 小时前
GESP2026年3月认证C++四级( 第二部分判断题(1-10))
c++·指针·函数重载·文件操作·数组·gesp4级·gesp四级