• 2020牛客寒假算法基础集训营4 H 坐火车


    https://ac.nowcoder.com/acm/contest/3005/H

    当我们要计算的车厢从第i个移到第i+1个的时候

    只会影响第i个车厢对应颜色的数量 和 第i+1个车厢对应颜色的数量

    用树状数组维护当前车厢左右所有颜色相同的车厢对数的前缀和

    假设已经计算完了前i个车厢的答案,现在要计算第i+1个车厢的答案

    若车厢i的颜色是a,车厢i+1的颜色是b

    除了a、b,其他颜色的左右相同的车厢对数是一样的

    对颜色a来说,第i个车厢可以做 左边那个车厢了

    第i个车厢后面有多少个颜色跟他一样的车厢(除去第i+1个车厢),这个颜色对答案的贡献就会增加多少

    对颜色b来说,第i+1个车厢不可以做 右边那个车厢了

    第i+1个车厢前面有多少个颜色跟他一样的车厢(除去第i个车厢),这个颜色对答案的贡献就会减少多少

    再用两个数组记录这个即可

    有一个点想了很久:

    求第i个车厢后面有多少个颜色跟他一样的车厢(除去第i+1个车厢)时,可以不用管“除去第i+1个车厢”这个条件

    后面也是

    因为如果第i和第i+1个车厢颜色相同,一加一减恰好抵消

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    #define N 500001
    
    #define lowbit(x) x&-x
    
    int col[N],L[N],R[N];
    int suml[N],sumr[N];
    
    long long c[N];
    
    void add(int x,int y)
    {
        while(x<N)
        {
            c[x]+=y;
            x+=lowbit(x);
        }
    }
    
    long long query(int x)
    {
        long long s=0;
        while(x)
        {
            s+=c[x];
            x-=lowbit(x);
        }
        return s;
    }
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%d%d%d",&col[i],&L[i],&R[i]);
            sumr[col[i]]++;
        }
        for(int i=1;i<=n;++i)
        {
            sumr[col[i]]--;
            add(col[i],-suml[col[i]]);
            printf("%lld ",query(R[i])-query(L[i]-1));
            suml[col[i]]++;
            add(col[i],sumr[col[i]]);
        }
        return 0;
    }
  • 相关阅读:
    brew
    hbase
    YARN常见问题以及解决方案
    mybatis中foreach collection三种用法
    mysql按分隔符输出多行
    mysql DATETIME
    iis 之给网站添加MIME映射
    VS2019专业版和企业版激活密钥
    ViewData对于从后台传list到前台的使用
    找出每组数据中不同distinct
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12302576.html
Copyright © 2020-2023  润新知