2019上海ICPC网络赛 B. Light bulbs【差分+思维】

B. Light bulbs

题意:

N 个 灯泡(编号 0 ~ N-1) M 次操作(初始灯都是关的)

每次操作 给 2个数 L, R,把[L, R]区间内的开关翻转

求 M次操作后 有多少灯开着

题解:
暴力 O(NT) 复杂度到达1e9 TLE
线段树 树状数组 O(T
N*logn)也会超时
这个题内存也很小,对M次操作进行处理。

先对m组数据存下来,按照从小到大排序。
差分数组
p【l】=1 p【r+1】=-1 理解为我们把 L 右边的所有灯全部转化,区间为L,R 所以我们还的把R+1 右边全部转化。

对着m*2个排好的数据进行操作,从最小的开始,用sum表示这个数到下一个数是奇数还是偶数,奇数的话变化了奇数次 ,就说明这个数到下个数变化了奇数次,这个数到下个数灯都是开着的,加上灯的个数 。变化偶数次都是关的。

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
struct  node{
	ll index,num;
}p[5000];
ll cmp(node a,node b)
{
	return a.index<b.index;
}
int main()
{
	ll t,k=1;
	scanf("%lld",&t);
	while(t--)
	{
		ll n,m,cnt=0;
		scanf("%lld%lld",&n,&m);
		for(int i=0;i<m;i++)
		{
			ll l,r;
			scanf("%lld%lld",&l,&r);
			p[cnt].index=l;
			p[cnt++].num=1;
			p[cnt].index=r+1;
			p[cnt++].num=-1;
		}
		
		sort(p,p+cnt,cmp);

		ll sum=0,ans=0;
		for(int i=0;i<cnt;i++)
		{
			sum+=p[i].num;
			if(sum&1)
				ans+=p[i+1].index-p[i].index;
		}
		printf("Case #%lld: %lld\n",k++,ans);
	}
	return 0;
 } 
发布了88 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43667611/article/details/100899258