题目链接:点击这里
题意就是:n个点m个区间,每次区间内的数+1,最后n个点中计数为奇数的点的个数就是答案。
卡数据卡内存,每组样例一重循环都会超时。所以可以分块和对m处理来做。
对m处理的话,仔细想一想,只有区间次数被操作奇数次的话,这个区间长度就可以加上,所以我们只要把左右端点从小到大排序然后区间求和就行了。
AC代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<map>
#include<set>
#include<iomanip>
#include<math.h>
using namespace std;
typedef long long ll;
typedef double ld;
const int N=1000010;
int n,t,m;
int i,j,k;
int cas=0;
int a[4010];
int l,r,cnt,ans;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
for(i=0; i<2*m; i++)
{
scanf("%d %d",&l,&r);
r++;
a[i++]=l;
a[i]=r;
}
m*=2;
ans=0;
sort(a,a+m);
for(i=1; i<m; i+=2)
{
ans+=a[i]-a[i-1];
}
cout<<endl;
printf("Case #%d: %d\n",++cas,ans);
}
return 0;
}
map做法:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<set>
#include<unordered_map>
#include<iomanip>
#include<math.h>
using namespace std;
typedef long long ll;
typedef double ld;
const ll INF=1e14;
int i,j,k;
int n,t,m,b;
int x,y;
int res,cnt,temp,sum;
int cas=0;
using namespace std;
struct node
{
bool fz;
int p;
} light[2005];
unordered_map<int,int> Map;
bool cmp(const node&a,const node&b)
{
return a.p<b.p;
}
int main()
{
int T,tot,n,m,l,r,idl,idr,cnt;
scanf("%d",&T);
cnt=0;
while(T--)
{
tot=0;
Map.clear();
scanf("%d%d",&n,&m);
while(m--)
{
scanf("%d%d",&l,&r);
if(!Map[l])
{
Map[l]=++tot;
light[tot].fz=0;
}
idl=Map[l];
light[idl].fz^=1;
light[idl].p=l;
int tr=r+1;
if(!Map[tr])
{
Map[tr]=++tot;
light[tot].fz=0;
}
idr=Map[tr];
light[idr].fz^=1;
light[idr].p=tr;
}
sort(light+1,light+tot+1,cmp);
int ans=0,x=-1,y;
bool st=0;
for(int i=1; i<=tot; i++)
{
if(light[i].fz==0)
continue;
if(x==-1)
{
x=light[i].p;
st^=1;
}
else
{
y=light[i].p;
if(st==1) ans+=y-x;
x=y;
st^=1;
}
}
printf("Case #%d: %d\n",++cnt,ans);
}
return 0;
}