zoukankan      html  css  js  c++  java
  • 2019年icpc上海网络赛 B Light bulbs (分块、差分)

    https://nanti.jisuanke.com/t/41399

    题目大意:

    有n个灯,m次操作,每次修改[l,r]内的灯,(off - on ,on - off),问最后有几盏灯亮着.

    换种说法:n个点m个区间,每次区间内的数+1,最后n个点中计数为奇数的点的个数就是答案。

    刚开始没注意,直接用线段树写,超内存了。。。。

    这题因为外层有个T,并且n太大,还要卡内存,太过分了。

    卡数据卡内存,每组样例一重循环都会超时。所以可以分块和对m处理来做。

    对m处理的话,仔细想一想,只有区间次数被操作奇数次的话,这个区间操作才有效,所以我们只要把左右端点从小到大排序然后区间求和就行了。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <math.h>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=1e7+10;
    17 using namespace std;
    18 int a[4010];
    19 
    20 int main()
    21 {
    22     int T;
    23     scanf("%d",&T);
    24     for(int k=1;k<=T;k++)
    25     {
    26         int n,m;
    27         int l,r;
    28         scanf("%d %d",&n,&m);
    29         for(int i=0;i<2*m;i++)
    30         {
    31             scanf("%d %d",&l,&r);
    32             a[i++]=l;
    33             a[i]=++r;
    34         }
    35         m*=2;
    36         int ans=0;
    37         sort(a,a+m);
    38 //        for(int i=0;i<m;i++)
    39 //        {
    40 //            printf("%d ",a[i]);
    41 //        }
    42         for(int i=1;i<m;i+=2)
    43         {
    44             ans+=a[i]-a[i-1];
    45         }
    46         printf("Case #%d: %d
    ",k,ans);
    47     }
    48     return 0;
    49 }

    对m下手,注意到:

    把每一个端点存起来之后(并且排序),毎两个点之间的区间的 亮与否至于左边有关,不包括右边.

    所以利用差分的思想,修改 L,R相当于a(L)+1,a(R+1)-1

    我们把端点 排好序之后,就直接跑一遍m 

    如果当前为左端点 则 覆盖层数++(意思就是 之后的每个数都多了一个区间覆盖)

    如果当前为右端点 则覆盖层数--(意思就是 之后每个数都少了一个覆盖区间)

    因为区间左闭右开,只要为奇数(灯亮),就加上左边右开区间 R-L的值

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <string>
    #include <math.h>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    #include <math.h>
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    const int mod=1e9+7;
    const int maxn=1e7+10;
    using namespace std;
    
    
    struct node
    {
        int f;
        int id;
        bool friend operator < (node a,node b)
        {
            if(a.id==b.id)
                return a.f<b.f;
            return a.id<b.id;
        }
    }pos[2010];
    
    int main()
    {
        int T;
        scanf("%d",&T);
        for(int k=1;k<=T;k++)
        {
            int n,m;
            int l,r;
            int cnt=0;
            scanf("%d %d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                scanf("%d %d",&l,&r);
                pos[++cnt].id=l;
                pos[cnt].f=0;
                pos[++cnt].id=r+1;
                pos[cnt].f=1;
            }
            int cot=0;
            int ans=0;
            sort(pos+1,pos+1+cnt);
            for(int i=1;i<=cnt-1;i++)
            {
                if(pos[i].f)
                    cot--;
                else
                    cot++;
                if(cot%2)
                    ans+=pos[i+1].id-pos[i].id;
                
            }
            printf("Case #%d: %d
    ",k,ans);
        }
        return 0;
    }
  • 相关阅读:
    上海python14期第一次周考
    day05总结
    day05作业
    day04总结
    js判断是安卓还是Ios
    移动端 --- 阻止浏览器点击图片会预览的方法
    meta标签禁止打电话 转载
    mac 常用命令
    ajax. 通过后台接口 渲染数据
    vue prop
  • 原文地址:https://www.cnblogs.com/jiamian/p/11524377.html
Copyright © 2011-2022 走看看