New Year and Ascent Sequence

A sequence a=[a1,a2,…,al] of length l has an ascent if there exists a pair of indices (i,j) such that 1≤i<j≤l and ai<aj. For example, the sequence [0,2,0,2,0] has an ascent because of the pair (1,4), but the sequence [4,3,3,3,1] doesn’t have an ascent.

Let’s call a concatenation of sequences p and q the sequence that is obtained by writing down sequences p and q one right after another without changing the order. For example, the concatenation of the [0,2,0,2,0] and [4,3,3,3,1] is the sequence [0,2,0,2,0,4,3,3,3,1]. The concatenation of sequences p and q is denoted as p+q.

Gyeonggeun thinks that sequences with ascents bring luck. Therefore, he wants to make many such sequences for the new year. Gyeonggeun has n sequences s1,s2,…,sn which may have different lengths.

Gyeonggeun will consider all n2 pairs of sequences sx and sy (1≤x,y≤n), and will check if its concatenation sx+sy has an ascent. Note that he may select the same sequence twice, and the order of selection matters.

Please count the number of pairs (x,y) of sequences s1,s2,…,sn whose concatenation sx+sy contains an ascent.

Input
The first line contains the number n (1≤n≤100000) denoting the number of sequences.

The next n lines contain the number li (1≤li) denoting the length of si, followed by li integers si,1,si,2,…,si,li (0≤si,j≤106) denoting the sequence si.

It is guaranteed that the sum of all li does not exceed 100000.

Output
Print a single integer, the number of pairs of sequences whose concatenation has an ascent.

Examples
Input
5
1 1
1 1
1 2
1 4
1 3
Output
9
Input
3
4 2 0 2 0
6 9 9 8 8 7 7
1 6
Output
7
Input
10
3 62 24 39
1 17
1 99
1 60
1 64
1 30
2 79 29
2 20 73
2 85 37
1 100
Output
72
Note
For the first example, the following 9 arrays have an ascent: [1,2],[1,2],[1,3],[1,3],[1,4],[1,4],[2,3],[2,4],[3,4]. Arrays with the same contents are counted as their occurences.
题目分析:
通过这个题确实明白了动态数组的好用,好多内部的函数对处理问题有很大的帮助。
思路:
首先明白所有序列有几种可能性。
只有两种序列:

  1. 上升序列。
  2. 非上升序列。

而这几种序列有几种组合的可能性呢?

  1. 上升+上升
  2. 上升+非升
  3. 非升+上升
  4. 非升+非升

而只要组合中有上升序列,那么它无论和什么序列组合都会产生满足题意的序列,数量是2*(n-1)+1,其中n为序列的个数总和,但是还存在一种情况,我们假设A,B,C均为上升序列,当前序列为A时,会产生AA,AB,BA,AC,CA这五种组合可能,当到下一个序列B时产生的组合可能为BB,BA,AB,BC,CB。这时候问题就暴露出来了,与先前A的可能序列产生了两个相同的序列,把这一点延伸一下,每多一个上升序列就会多出重复的两个序列,那么我们在答案加2*(n-1)+1时,每加一次就n–一次,这样就正确了。
那么现在四种组合处理了三种了,只剩下一种了。那么最后一种组合也很简单,吧所有非升序列的最大值与最小值存在一个动态数组做中,当然不是动态数组也没事,之后按升序排列,然后设置一个指针pos,从头开始比较最大值与最小值,当出现比最大值大的最小值时,就停止pos移动,对答案ans加上pos(实际上是把最小值放在最大值前面,这样无论如何都能组成一个满足题意的序列)。
具体细节还是要看代码才能明白:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
vector<ll>minx,maxx;
ll ans=0;
int main()
{
    int q;
    scanf("%d",&q);
    int qq=q,tot=0;
    while(q--)
    {
        int n,x,mi=9999999,ma=-1,flag=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(x>mi) flag=1;
            mi=min(mi,x);
            ma=max(ma,x);
        }
        if(flag) {
            ans+=2*qq-1;//每多一个序列就会减少两个重复的
            qq--;
        }
        else {
            minx.push_back(mi);
            maxx.push_back(ma);
            tot++;//有几个非增序列
        }
    }
    sort(minx.begin(),minx.end());
    sort(maxx.begin(),maxx.end());
    ll pos=0;
    for(int i=0;i<tot;i++)
    {
        while(maxx[i]>minx[pos]&&pos<tot) pos++;//由于最大值和最小值数组是升序排列的,所以只要最大值大于minx[pos]那么前面的都会大于
        ans+=pos;
    }
    printf("%lld",ans);
    return 0;
}
发布了59 篇原创文章 · 获赞 58 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/amazingee/article/details/104693418