Codeforces 396 E. Valera and Queries

题目链接:http://codeforces.com/problemset/problem/369/E


  考虑将问题转化为有多少条线段没有覆盖这些点,如果一个询问的点集是${[x1,x2,...,xn]}$那么相当于询问有多少条线段在${\left [ 1,x1 \right )\bigcup (x1,x2)\bigcup ...(x_{n-1},x_n)\bigcup(x_n,1e6+1)}$这个范围内,所以离线询问,从左至右扫过去,每到一个点就把以这个点为右端点的线段的左端点的位置加入到树状数组中,然后统计答案

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
using namespace std;
#define llg int
#define maxn 1000100
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg ans[maxn],n,m,c[maxn];
vector<llg>q[maxn],belong[maxn],line[maxn]; inline llg getint()
{
llg w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar();
if (c=='-') q=, c=getchar(); while (c>='' && c<='') w=w*+c-'', c=getchar();
return q ? -w : w;
} void inc(llg x) {for (;x<maxn;x+=x&-x) c[x]++;} llg sum(llg x) {if (x==) return ; llg val=; for (;x>;x-=x&-x) val+=c[x]; return val;} void init()
{
cin>>n>>m;
for (llg i=;i<=n;i++)
{
llg l=getint(),r=getint();
line[r].push_back(l);
}
for (llg i=;i<=m;i++)
{
ans[i]=n;
llg k=getint(),x=;
for (llg j=;j<=k;j++)
{
llg wz=getint();
q[wz].push_back(x);
belong[wz].push_back(i);
x=wz;
}
q[].push_back(x);
belong[].push_back(i);
}
} int main()
{
yyj("ds");
init();
for (llg i=;i<=;i++)
{
llg w=q[i].size();
for (llg j=;j<w;j++)
{
ans[belong[i][j]]-=sum(i-)-sum(q[i][j]);
}
w=line[i].size();
for (llg j=;j<w;j++)
{
llg x=line[i][j];
inc(x);
}
}
for (llg i=;i<=m;i++) printf("%d\n",ans[i]);
return ;
}
上一篇:Listview Section 多个标题以及内容


下一篇:Android HandlerThread的用法