问题 C: 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

题目意思:

给定一个由n个整数组成的数组,请确定该数组中有多少个连续的子序列不包含任何重复值。注意,将考虑两个内容相同的子序列
如果它们从原始长数组的不同位置开始,则表示不同(即,两者均计入总数)。

这个连续的序列中不能有重复的数字

例一:1,1,2,1,5,1 1,1 2,1 5,2 1 5,

这个题就是算每一个元素的贡献,例如 1:1(本身)   1:2(1,1 2)   2:(2,2 1,2 1 5)   1:(1, 1 5)       5:(5)

 

这个就是对列的应用,例:队列中有1 ans+=1,然后进入1就向前找把1给pop掉ans+=1(q.size(),然后进入2,ans+=q.size(),

ans就是4,然后进入1然后再把对列前面的1pop,ans+=2,ans=6,然后5进入就是ans+=3,就是9

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
ll a[N];
deque<ll> q;
map<ll,ll> vis;
int main()
{
    ll n;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        if(!vis[a[i]])
        {
            q.push_back(a[i]);
            vis[a[i]]++;
        }
        else{
            q.push_back(a[i]);
            vis[a[i]]++;
            while(q.size()&&vis[a[i]]>=2)
            {
                vis[q.front()]--;
                q.pop_front();
            }
        }
        ans+=q.size();
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2020-10-11 10:03  哎呦哎(iui)  阅读(303)  评论(0编辑  收藏  举报