zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    如何使用jetty
    windows安装TortoiseGit详细使用教程【基础篇】
    shiro实现APP、web统一登录认证和权限管理
    Eclipse上安装GIT插件EGit及使用
    RPC之——HTTP协议栈
    Spring Boot构建RESTful API与单元测试
    Spring 之注解事务 @Transactional
    浅析Java中的final关键字
    String中intern的方法
    MySQL索引的查看创建和删除
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12302576.html
Copyright © 2011-2022 走看看