• 2019上海icpc网络赛B. Light bulbs(思维+差分)


    题目传送门

    题意

    T组案例,每组案例:n个灯泡(from 0 to n-1),m次操作,每次操作把区间[L,R]内的灯泡翻转(开变关,关变开),问m次操作之后有多少灯泡是亮着的。(时间限制:1000ms  内存限制:8192K)

    题解

    这道题不仅卡时间,更是卡内存,所以用线段树会爆内存

    正解:

    该题可以转换为经典的差分问题:每次操作对[L,R]的所有数进行+1操作,求最后有多少个奇数。(设该数组为a[n],每次操作a[L]+1,a[R+1]-1,求前缀和sum[i]=sum[i-1]+a[i]即可得到进行区间所有数+1操作后每个数的值sum[i])

    利用差分的思想,但如果是遍历n还是会超时超内存,此题m较小,所以可以从m下手,只需存端点,最后遍历所有端点即可。官方题解如下:

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2005;
    pair<int,int>p[maxn];
    int main()
    {
        int T,cas=0;
        scanf("%d",&T);
        while(T--){
            int n,m,l,r,cnt=0;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++){
                scanf("%d%d",&l,&r);
                p[cnt++]=make_pair(l,1);
                p[cnt++]=make_pair(r+1,-1);
            }
            sort(p,p+cnt);
            int sum=0,now=0,ans=0;
            for(int i=1;i<cnt;i++){
                sum+=p[i].second;
                if(sum&1)
                    ans+=p[i].first-p[i-1].first;
            }
            printf("Case #%d: %d
    ",++cas,ans);
        }
        return 0;
    }

    差分:

    何为差分?差分就是将数列中的每一项分别与前一项数做差。

    例如:原数列a[n],差分数列b[n],b[i]=a[i]-a[i-1],a[i]=差分数列的前缀和sum[i]。

    (注意:1.差分序列的第一个数和原来的第一个数一样,相当于第一个数去减0;2.差分序列最后会比原序列多一个数,相当于0减最后一个数)

    一个序列原本为 1 3 5 2 9 3,差分后得到 1 2 2 -3 7 -6。

    两个性质:

    ①差分序列求前缀和可得原序列;

    ②原序列区间[L,R]中的元素全部+K,可以转化操作为差分序列L处+K,R+1处-K;

  • 相关阅读:
    微信小程序之项目的创建
    Java中的线程--多线程面试题
    Java中的线程--并发库中的集合
    Java中的线程--线程中的工具
    Java中的线程--Lock和Condition实现线程同步通信
    Linux指定用户运行程序
    CPU、内存、磁盘三者的关系
    shell从字符串中提取子串(正则表达式)
    ssh登录失败的常见问题分析
    正则表达式匹配不含有某字符串的行
  • 原文地址:https://www.cnblogs.com/HOLLAY/p/11533869.html
Copyright © 2020-2023  润新知