zoukankan      html  css  js  c++  java
  • 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;

  • 相关阅读:
    操作数据库插入,更新中文信息出现乱码
    ServletResponse使用介绍
    Tomcat乱码问题
    ServletRequest使用介绍
    Servlet的生命周期
    方法重写与方法重载的区别
    Java异常ClassCastException
    异常java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value
    CentOS7通过源码安装nginx
    LDA与PCA
  • 原文地址:https://www.cnblogs.com/HOLLAY/p/11533869.html
Copyright © 2011-2022 走看看