Unique Values(思维)

题目描述
Arup has to make many practice questions for his Computer Science 1 students. Since many of the questions deal with arrays, he has to generate arrays for his students. Since he doesn’t want to
give them difficult practice problems, he always guarantees that the arrays (given to the students) have unique values. Namely, no value will appear twice in any of his arrays.

Unfortunately, Arup is too lazy to generate arrays! About 20 years ago when he started teaching Computer Science 1, he made one really long array to reuse but this long array may have duplicate
values. When he makes problems, he simply grabs a contiguous subsequence of this long array to be the array to be used for a problem but he needs to make sure the contiguous subsequence does
not contain duplicates. If the long array has terms a[0], a[1], …, a[n-1], a contiguous subsequence of the long array is any sequence of j – i + 1 terms a[i], a[i+1], …, a[j] where 0 ≤ i ≤ j ≤ n – 1.

Given an array of n integers, determine how many contiguous subsequences of the array do not contain any repeated values. Note that two subsequences with the same contents are considered
different (i.e., both counted in the total) if they start at different locations of the original long array.
输入
The first input line contains a single positive integer, n (1 ≤ n ≤ 105 ), representing the size of the input array. The following line contains n space separated integers, representing the values of the
input array, in the order they appear in the array. Each of the array values will be an integer between 1 and 109 , inclusive.
输出
On a line by itself, output the total number of contiguous subsequences of the input array that do not contain any repeated values.
样例输入 Copy
【样例1】
5
1 1 2 1 5
【样例2】
8
2 12 3 12 3 2 6 9
样例输出 Copy
【样例1】
9
【样例2】
22

题意

就是给出你一段序列让你求得总的不重复长度,在每个位置上只能加上一个最大的数。

思路

因为让我选取的长度中不能有重复的。所以我们就把它尾端用指针最后一个标记上,如果在遇到相同的,把指针转移到现在这个这样我们就可以维护一个没有重复的长度了。

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
#include <immintrin.h>
#pragma GCC optimize(2)
#include <map>
#include <queue>
#include <string>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
typedef pair<ll,ll> pii;
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
const int maxn=2e5+1010;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod=998244353;
const int MOD=10007;

inline int read() {
	int x=0;
	bool t=false;
	char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
ll n;
ll a[maxn];
map<ll,ll>mp;
#define read read()
int main(){
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    ll i,j=0;
    ll sum=0;
    for(i=1;i<=n;i++){
        if(mp[a[i]]){
            j=max(j,mp[a[i]]);
            mp[a[i]]=i;
            sum+=i-j;

        }else {
            sum+=(i-j);
            mp[a[i]]=i;
        }
    }
    cout<<sum<<endl;
	return 0;
}



这个是队友写的比较快的版本。

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 7;
const ll mod = 1000000009;

#define mst(x, a) memset( x,a,sizeof(x) )
#define rep(i, a, b) for(int i=(a);i<=(b);++i)
#define dep(i, a, b) for(int i=(a);i>=(b);--i)

inline ll read() {
	ll x = 0;
	bool f = 0;
	char ch = getchar();
	while (ch < '0' || '9' < ch) f |= ch == '-', ch = getchar();
	while ('0' <= ch && ch <= '9')
		x = x * 10 + ch - '0', ch = getchar();
	return f ? -x : x;
}

void out(ll x) {
	int stackk[20];
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (!x) {
		putchar('0');
		return;
	}
	int top = 0;
	while (x) stackk[++top] = x % 10, x /= 10;
	while (top) putchar(stackk[top--] + '0');
}
ll n,a[maxn],b[maxn],vis[maxn],ans;

int main() {
	n=read();
	rep(i,1,n) b[i]=a[i]=read();
	sort(b+1,b+1+n);
	ll pos=unique(b+1,b+1+n)-(b+1);
	rep(i,1,n) a[i]=lower_bound(b+1,b+1+pos,a[i])-b;
	ll p=0;
	for(int i=1 ; i<=n ; i++) {
		if(vis[a[i]]==0) {
			ans+=(i-p);
		} else {
			p=max(p,vis[a[i]]);
			ans+=(i-p);
		}
		vis[a[i]]=i;
	}
	out(ans);
	return 0;
}
/*

*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值