标签:cnt int 查集 4412 ++ 数组 区间 AcWing
AcWing 4412. 构造数组(三种解法)
思路分析
经分析可得,
\[若a_i = a_j,则 b_i <= b_{i + 1} <= ... <= b_j\\ 又\because b_i=b_j\,\,\,\therefore b_i = b_{i + 1} = ... = b_j \]所以只需要去统计有多少个这样的区间,然后乘2即可(因为每一个区间都有两种选择)
法一:区间合并
防止umap被卡的小技巧:1. 初始化一个大的长度(见代码);2. here;3.换成map
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 998244353, N = 2e5 + 5;
int n, m, cnt;
pair <int, int> p[N];
void test() {
for (int i = 0; i < m; i ++)
cout << p[i].first << ' ' << p[i].second << endl;
}
signed main () {
unordered_map <int, int> L(300000), R(300000);
cin >> n ;
for (int i = 1; i <= n; i ++) {
int t;cin >> t;
R[t] = i;
if (!L.count(t))
L[t] = i; //左端点只用更新一次
}
int m = 0;
for (auto& [i, v]:L) //高级做法 C++17才能用
p[m ++] = {L[i], R[i]};
sort (p, p + m);
//test();
int l = -1, r = -1;
cnt = m;
for (int i = 0; i < m; i ++) {
if (p[i].first <= r)
r = max (r, p[i].second), cnt --;
else
l = p[i].first, r = p[i].second;
}
int ans = 0;
cnt --;
for (int i = 0; i < cnt; i ++)
ans = ans * 2 % mod;
cout << ans << endl;
}
//bi 到 bj之间的所有数字都要相等
//按照段来划分
法二:离散化 + 差分
染色思想:点坐标 * 2,统计被覆盖的次数,出现0就代表该区间结束,准备进入下一个区间
法三:并查集
这是一种通用思路(并查集常见操作)
把整体视为一个长线段。
每一个区间内的点都向右端点合并,最后就可以统计区间个数了
标签:cnt,int,查集,4412,++,数组,区间,AcWing 来源: https://www.cnblogs.com/CTing/p/16185375.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。