• 2019牛客暑期多校训练营(第八场)B-Beauty Values(期望线性性)


    >传送门<

    题意:
    思路:期望的线性性(可加性)比赛的时候写的代码超级无敌长,不过值得欣慰的是一发AC了,官方的题解写的还不错~

    我们可以把每种数字对答案的贡献分开来计算,即枚举每个数字,求原序列有多少个子区间包含至少一个该 数字,最后把答案累加起来即可。

    问题在于求序列有多少个子区间包含至少一个某数字,既可以直接计算,也可以考虑用全集减去不包含的子区间。不包含的子区间的个数可以枚举相邻两个数字,并累加中间空隙的子区间个数,再统计一下边界即可。 时间复杂度为O(n)

    下面给出直接计算的代码

    Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll v[100005];
    int main()
    {
        int n;
        cin>>n;
        ll ans = 0, a;
        for(int i=1;i<=n;i++){
            cin>>a;
            ans += (n-i+1)*(i-v[a]);
            v[a] = i;
        }
        cout<<ans<<endl; 
    }

    n-i+1表示的是当前数字a能影响到的后面区间数量,i-v[a](避免重复计算)表示的是当前a向左延伸直到上一个a间的区间数量+空区间,两者相乘即得到当前数字能影响到的区间,最后把每个数字相加起来就是答案。

    举个栗子,就拿题目中的[1,2,1,3]来说

    当扫描到i = 3时,这个1能影响到的区间有[3,3] = {1},[3,4] = {1,3},[2,3] = {2,1},[2,4] = {2,1,3},[1,3] = {1,2,1},[1,4] = {1,2,1,3}

    但是你马上会发现此时这个1能影响到的区间和第一个1能影响的区间有一部分重合了,怎么办?

    那我就只让这个1影响的区间向左扩散,直到碰到1就停下,即向左扩散只影响这两个1间的区间就行了

    对于[7,6,2,1,3,4,1,5,9]而言

    当i = 7,v[a] = 4(上一个a的位置),向后影响到9-7+1=3个区间( {1},{1,5},{1,5,9} ),向前影响到7-4=3个区间( {Ø},{2},{6,2},{7,6,2}),总共能影响到9个区间

  • 相关阅读:
    浅谈ssh(struts,spring,hibernate三大框架)整合的意义及其精髓
    Spring中ClassPathXmlApplicationContext类的简单使用
    测试计划/系统风险 (设计方面、开发方面、测试本身 等风险)
    浏览器兼容
    4.0 爬虫
    2.1 IDEA
    2.3 接口测试
    1.1测试分类
    1.3 ODPS
    2.1 Word 插入 smartart、图表
  • 原文地址:https://www.cnblogs.com/wizarderror/p/11340957.html
Copyright © 2020-2023  润新知