1 条题解
-
0
思路
要统计满足 、且数值为 的那个位置在三点中最小或最大的三元组。
设数值 的位置为 。另外两个位置分别是 和 。“ 最小或最大”排除了 在中间的情况,剩下的合法顺序只有四种:
- ( 最左)
- ( 最左)
- ( 最右)
- ( 最右)
统计时分两个方向做:
从右往左扫描 —— 已统计的元素都在当前元素右侧,于是可以统计 位于下标最大处(最右)的两种顺序:
c__5[x]:右侧出现过的 个数;c_75[x]:右侧已形成的 二元组个数;c_35[x]:右侧已形成的 二元组个数;c735[x]、c375[x]:已凑成的 、 三元组个数。
遇到 时:先用
c_35把它补成三元组(),再把当前 与右侧的 组成新的二元组()。 遇到 时:先用c_75把它补成三元组(),再与右侧的 组成新的二元组()。从左往右扫描同理,统计 位于下标最小处(最左)的两种顺序,对应
c537()与c573(),二元组为c53_()和c57_()。最后把四种三元组的计数相加即为答案。
注意:
- 一个数可能同时是 、、(例如 ),代码中三个
if是独立的、互不else,因此可以分别扮演三种角色。 - 结果最大约为 ,超出 32 位整数,代码用
#define int long long。
复杂度: 时间 (
map每次操作对数级),空间 。代码
#include<bits/stdc++.h> #define int long long #define dd double #define str string #define el cout << '\n' #define re return #define ff first #define ss second #define pll pair<int,int> #define pdd pair<dd,dd> #define all(x) x.begin(),x.end() #define pb push_back using namespace std; void go(){ int n;cin>>n; vector<int>a(n+1, 0); for(int i=1;i<=n;i++){ cin>>a[i]; } // 从右向左扫描:统计 5x 位于最右侧的两种顺序 // 键 x 表示同比例的一组数 (3x, 5x, 7x) map<int, int>c__5, c_35, c735, c_75, c375; for(int i=n;i>0;i--){ // 当前数是 5x,右侧所有 5x 都能和它配对 if(a[i]%5==0){ c__5[a[i]/5]++; } if(a[i]%7==0){ // 当前数是 7x c735[a[i]/7] += c_35[a[i]/7]; // 7x + (3x→5x) 凑成 7x→3x→5x c_75[a[i]/7] += c__5[a[i]/7]; // 7x 与右侧的 5x 组成新二元组 } if(a[i]%3==0){ // 当前数是 3x c375[a[i]/3] += c_75[a[i]/3]; // 3x + (7x→5x) 凑成 3x→7x→5x c_35[a[i]/3] += c__5[a[i]/3]; // 3x 与右侧的 5x 组成新二元组 } } // 从左向右扫描:统计 5x 位于最左侧的两种顺序 map<int, int>c5__, c53_, c537, c57_, c573; for(int i=1;i<=n;i++){ if(a[i]%5==0){ c5__[a[i]/5]++; } if(a[i]%7==0){ c537[a[i]/7] += c53_[a[i]/7]; // (5x→3x) + 7x 凑成 5x→3x→7x c57_[a[i]/7] += c5__[a[i]/7]; // 5x→7x 二元组 } if(a[i]%3==0){ c573[a[i]/3] += c57_[a[i]/3]; // (5x→7x) + 3x 凑成 5x→7x→3x c53_[a[i]/3] += c5__[a[i]/3]; // 5x→3x 二元组 } } // 四种顺序的三元组计数之和 int ans = 0; for(auto [num, cnt]:c375){ans += cnt;} for(auto [num, cnt]:c735){ans += cnt;} for(auto [num, cnt]:c537){ans += cnt;} for(auto [num, cnt]:c573){ans += cnt;} cout<<ans;el; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); int _=1; // 本题只有单组数据 while(_--){ go(); } return 0; }
- 1
信息
- ID
- 21
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者