您的位置:首页 > 其它

[主席树 强制在线]ZOJ3888 Twelves Monkeys

2015-07-26 22:38 288 查看
题意:有n年,其中m年可以乘时光机回到过去,q个询问

下面m行,x,y 表示可以在y年穿越回x年, 保证y>x

下面q个询问, 每个询问有个年份k

问的是k年前面 有多少年可以通过一种以上($\ge 2$)方法穿越回去的, 其中时光机只能用一次

比如案例

9 3 3
9 1
6 1
4 1
6
7
2


如图

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PI;
#define lson l, m
#define rson m+1, r
const int N=50005;
int L[N<<5], R[N<<5], sum[N<<5];
int tot;
int T
, Hash
;
int build(int l, int r)
{
int rt=(++tot);
sum[rt]=0;
if(l<r)
{
int m=(l+r)>>1;
L[rt]=build(lson);
R[rt]=build(rson);
}
return rt;
}

int update(int pre, int l, int r, int x)
{
int rt=(++tot);
L[rt]=L[pre], R[rt]=R[pre], sum[rt]=sum[pre]+1;
if(l<r)
{
int m=(l+r)>>1;
if(x<=m)
L[rt]=update(L[pre], lson, x);
else
R[rt]=update(R[pre], rson, x);
}
return rt;
}

int query(int u, int v, int l, int r, int k)
{
if(l>=r)
return l;
int m=(l+r)>>1;
int num=sum[L[v]]-sum[L[u]];
if(num>=k)
return query(L[u], L[v], lson, k);
else
return query(R[u], R[v], rson, k-num);
}

PI a
;

int main()
{
int n, m, q;
while(~scanf("%d%d%d", &n, &m, &q))
{
tot=0;
int mm=0;
for(int i=1; i<=m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
if(x>y)
a[++mm]=make_pair(x, y);
}
m=mm;
sort(a+1, a+1+m);
for(int i=1;i<=m;i++)
Hash[i]=a[i].second;
sort(Hash+1, Hash+1+m);
int d=unique(Hash+1, Hash+1+m)-Hash-1;
T[0]=build(1, d);
for(int i=1; i<=m; i++)
{
int x=lower_bound(Hash+1, Hash+1+d, a[i].second)-Hash;
T[i]=update(T[i-1], 1, d, x);
}
while(q--)
{
int k;
scanf("%d", &k);
int p=lower_bound(a+1, a+1+m, make_pair(k, 0))-a;
if(m-p<1)
{
puts("0");
continue;
}
int x=query(T[p-1], T[m], 1, d, 2);
int ans=k-Hash[x];
if(ans<=0)
puts("0");
else
printf("%d\n", ans);
}
}
return 0;
}


ZOJ 3888
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: