2019上海网络赛B.Light bulbs (差分)

题意:

T组案例
每组案例:
n个灯泡,m次操作
每次操作把区间(L,R)内的灯泡翻转(开变关,关变开)
问m次操作之后有多少灯泡是亮着的

链接

数据范围:

T<=1e3
n<=1e6
m<=1e3
时限1s,内存8000k

分析:

空间小时间少恶心人
差分每组O(n)都tle

但是因为m小,所以考虑从m入手
比赛的时候一手离散化+差分过了(600+ms)
但是刚刚看到别人的代码发现比自己的好很多(300+ms,不是离散化)
学习记录一下

下面挂两种代码:

code:

别人那边学到的

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
int read(){
    int x=0;char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x;
}
using namespace std;
const int maxm=1e3+5;
struct Node{
    int id,f;
}q[maxm<<2];
bool cmp(Node a,Node b){
    return a.id<b.id;
}
signed main(){
    int T=read();
    int cas=1;
    while(T--){
        int n=read(),m=read();
        int cnt=0;
        for(int i=1;i<=m;i++){
            int l=read(),r=read();
            q[++cnt].id=l;q[cnt].f=1;//差分左端点
            q[++cnt].id=r+1;q[cnt].f=-1;//差分右端点
        }
        sort(q+1,q+1+cnt,cmp);
        int sum=0;
        int ans=0;
        for(int i=1;i<=cnt-1;i++){
            sum+=q[i].f;
            if(sum%2)ans+=q[i+1].id-q[i].id;
        }
        printf("Case #%d: %d\n",cas++,ans);
    }
    return 0;
}

code:

我的

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
int read(){
    int x=0;char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x;
}
using namespace std;
const int maxm=1e3+5;
struct Node{
    int l,r;
}q[maxm];
int xx[maxm*4];
int mark[maxm*4];
signed main(){
    int T;
    scanf("%d",&T);
    int cas=1;
    while(T--){
        int n=read(),m=read();
        int num=0;
        for(int i=1;i<=m;i++){
            q[i].l=read();
            q[i].r=read();
            xx[++num]=q[i].l;
            xx[++num]=q[i].l+1;
            xx[++num]=q[i].r;
            xx[++num]=q[i].r+1;
        }
        sort(xx+1,xx+num+1);
        num=unique(xx+1,xx+1+num)-xx-1;
        for(int i=1;i<=num;i++){
            mark[i]=0;
        }
        for(int i=1;i<=m;i++){
            q[i].l=lower_bound(xx+1,xx+1+num,q[i].l)-xx;
            q[i].r=lower_bound(xx+1,xx+1+num,q[i].r)-xx;
            mark[q[i].l]++;
            mark[q[i].r+1]--;
        }
        int ans=0;
        int sum=0;
        for(int i=1;i<=num;i++){
            sum+=mark[i];
            if(sum%2)ans+=xx[i+1]-xx[i];
        }
        printf("Case #%d: %d\n",cas++,ans);
    }
    return 0;
}
上一篇:实时渲染的三种渲染方法介绍


下一篇:如何使用ephem库确定它是否是python中的白天(外面的光?)