Codeforces 905 (div2 C or div3 F) 题解

本文介绍了如何使用双指针技巧解决Codeforces905题,寻找在一个数组中只出现一次的连续子串。关键点在于判断子串的独特性,利用map存储元素首次出现位置,通过比较左右边界找到唯一子串并计算其数量。
摘要由CSDN通过智能技术生成

Codeforces 905 (div2 C or div3 F) 题解

Problem - F - Codeforces

题目概述:在数组中取出一个连续的字串,如果该字串只在数组中出现过一次(注意:出现的含义是找不出另外一个字串和它全等,不管这个字串是连续的还是不连续的,如

4
2 3 2 1

其中 [2,1] 出现了两次,分别是下标[0,3]和下标[2,3],故子串(2,1)不符合条件)。算出有多少个子串是唯一的。

类型:双指针

要点注意:

1.如果该字串是唯一的话,应该满足两个条件中的其中一个。要么该字串的长度与其他字串的长度不同(所以数组本身就是一个唯一的字子串),要么该字串的长度与其他字串相同,但字串的内容不与其他字串全等。根据“用于检验的字串可以不连续”这个性质,我们可以发现,只有最左端出现的数字是从最左端开始第一次出现的 和 最右段出现的数字是从最右端开始第一次出现的 ,这个字串才是唯一的。所以我们可以通过这个特性来通过双指针,用O(N)的时间复杂度求出这道题。

//
// Created by Mrlaolu on 2024/1/14.
//
#include<bits/stdc++.h>

#define int long long
#define endl '\n'
using namespace std;

const int N = 1010;

void solve()
{
  int n;
  cin >> n;
  vector<int>a(n);

  for(int i = 0;i < n;++i)
    cin >> a[i];

  map<int,int>checkl;          //用来检查是不是第一次出现
  vector<int>llac;			   //存数字第一次出现的位置

  map<int,int>checkr;
  vector<int>rlac;

  for(int i = 0;i < a.size();++i)
  {
    if(!checkl[a[i]])
    {
      checkl[a[i]] = i + 1;
      llac.push_back(i);
    }
  }

  for(int i = a.size() - 1;i > -1;--i)
  {
    if(!checkr[a[i]])
    {
      checkr[a[i]] = i + 1;
      rlac.push_back(i);
    }
  }

  int sum = 0;
  int r = rlac.size() - 1;

  for(int l = 0;l < llac.size();++l)
  {
    while(llac[l] > rlac[r])
    {
      r--;
    }
    sum += r + 1;
  }

  cout << sum << endl;

}
signed main()
{

  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值