传送门
题意:N个灯泡,m次操作,每次选定一个区间,将这些灯泡的状态反转,求最后亮着的灯泡的数量。
思路: 差分,线段树 ,分块应该都可以,但这题卡时间,卡内存,差分是正解。
区间反转奇数次的才需要统计,偶数次的不需要 , 例如 ;(1,6)(4,8)只需统计(1,3)和(7,8)
差分 正解
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <math.h>
#define mems(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e5+5;
struct node
{
int a,b;
}s[2010];
bool cmp(node x,node y)
{
return x.a<y.a;
}
int main()
{
int t,p=1 ;
scanf("%d",&t);
while(t--)
{
int n,m;
int cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
s[++cnt].a=l;
s[cnt].b=1;
s[++cnt].a=r+1;
s[cnt].b=-1;
}
sort(s+1,s+cnt+1,cmp);
int sum=0;int ans=0;
for(int i=1;i<=cnt;i++)
{
sum+=s[i].b;
if(sum&1)
ans+=s[i+1].a-s[i].a;
}
printf("Case #%d: %d\n",p++,ans);
}
}
线段树 动态开点 卡时间过去的
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <map>
#include <iterator>
#include <vector>
#include <set>
#include <bitset>
#include <stack>
#define ull unsigned long long
#define Mod(x) (x+mod)%mod
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define mems(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e5+5;
const double pi=acos(-1);
const int inf=0x3f3f3f3f;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
int id;
struct node
{
int sum,l,r,lazy;
}se[N];
inline int build()
{
++id;
se[id].l=se[id].r=se[id].sum=0;
se[id].lazy=0;
return id;
}
void pushdown(int l,int r,int rt)
{
if(se[rt].lazy==0) return;
int mid=(l+r)>>1;
if(l!=r)
{
if(se[rt].l==0) se[rt].l=build();
if(se[rt].r==0) se[rt].r=build();
se[se[rt].l].sum=(mid-l+1)-se[se[rt].l].sum;
se[se[rt].r].sum=(r-mid)-se[se[rt].r].sum;
se[se[rt].l].lazy^=1;
se[se[rt].r].lazy^=1;
}
se[rt].lazy=0;
}
void update(int l,int r,int L,int R,int rt)
{
if(L<=l&&r<=R)
{
se[rt].lazy^=1;
se[rt].sum=(r-l+1)-se[rt].sum;
return ;
}
pushdown(l,r,rt);
int mid=(l+r)>>1;
if(L<=mid)
{
if(se[rt].l==0)
se[rt].l=build();
update(l,mid,L,R,se[rt].l);
}
if(R>mid)
{
if(se[rt].r==0)
se[rt].r=build();
update(mid+1,r,L,R,se[rt].r);
}
se[rt].sum=se[se[rt].l].sum+se[se[rt].r].sum;
}
int main()
{
int u,p=1;
u=read();
while(u--)
{
int n,m;
n=read();m=read();
id=0;
build();
for(int i=1;i<=m;i++)
{
int l,r;
l=read();r=read();
l++;r++;
update(1,n,l,r,1);
}
printf("Case #%d: %d\n",p++,se[1].sum);
}
return 0;
}