SCUT校赛129:笔芯值(数学)

本文介绍了一种计算序列bx值的方法,bx值定义为序列中不连续递增元素的位置计数。文章提供了一个C++实现方案,通过计算序列的bx值并调整连续子序列的影响来得出最终结果。

题目描述

对于一个nn个数的序列 a_1,a_2,\cdots,a_na1,a2,,an,从小到大排序之后为a_{p_1},a_{p_2},\cdots,a_{p_n}ap1,ap2,,apn,定义它的 bxbx 值为满足 a_{p_i} \neq a_{p_{i-1}}+1, 1 < i \leq napiapi1+1,1<in 的 ii 的个数。

给定 nn 个数的一个排列,你需要计算它所有连续子序列的 bxbx 值之和。


输入格式

输入第一行包括一个正整数 TT,表示数据组数。
对于每组数据,第一行一个整数 nn,第二行 nn 个整数,表示 nn 个数的一个排列。
1 \leq T \leq 201T20
1 \leq n \leq 1000001n100000
1 \leq a_i \leq n1ain


输出格式

对每组数据输出一个整数表示答案。


样例数据

输入

2
3
1 2 3
4
3 1 4 2

输出

0
5

思路:先计算n个数总的bx值,连续子序列长度为x对答案做出的贡献为(n-(x-1))*(x-1),再减去非法的个数。具体做法就是对这n个数的下标排序,连在一起的下标就是非法的,比如a[3] = 7,a[6] = 8,那么包含下标3和6的连续子序列都需要减去1,那么这样的序列有3*(n-6+1)个。

# include <bits/stdc++.h>
# define ll long long

using namespace std;
const int maxn = 1e5;
ll a[maxn+3];
int c[maxn+3];
int main()
{
    int t, n;
    scanf("%d",&t);
    while(t--)
    {
        ll ans = 0;
        scanf("%d",&n);
        for(int i=1; i<=n; ++i)
        {
            scanf("%d",&a[i]);
            c[a[i]] = i;
            ans += (ll)(n-i+1)*(i-1);
        }
        for(int i=1; i<n; ++i)
        {
            int l = c[i], r = c[i+1];
            if(l > r) swap(l, r);
            ans -= (ll)l*(n-r+1);
        }
        printf("%lld\n",ans);
    }
    return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值