您的位置:首页 > 其它

zoj 3888 线段树 ***

2015-08-17 18:29 316 查看
卡n^2,用线段树降到nlogn

记录每个点上所覆盖线段的次小值,保证能有两条路径能走

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define MOD 1000000007
const int INF=0x3f3f3f3f;
const double eps=1e-5;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root 1,n,1
#define mid ((l+r)>>1)
typedef long long ll;
#define cl(a) memset(a,0,sizeof(a))
#define ts printf("*****\n");
const int N=51005;
int n,m,tt;
int a[N<<4],b[N<<4];
void pushdown(int rt)
{
//printf("pd:%d %d %d\n",a[rt],b[rt],rt);
if(b[rt]!=9999999)
{
if(b[rt]>=a[rt<<1]&&b[rt]<b[rt<<1])
{
b[rt<<1]=b[rt];
}
if(b[rt]<a[rt<<1])
{
a[rt<<1]=b[rt<<1];
a[rt<<1]=b[rt];
}
if(b[rt]>=a[rt<<1|1]&&b[rt]<b[rt<<1|1])
{
b[rt<<1|1]=b[rt];
}
if(b[rt]<a[rt<<1|1])
{
b[rt<<1|1]=a[rt<<1|1];
a[rt<<1|1]=b[rt];
}
b[rt]=9999999;
}
/*if(rt==4)
{
printf("%d %d\n",a[rt<<1],b[rt<<1]);
}*/
if(a[rt]!=9999999)
{
if(a[rt]>=a[rt<<1]&&a[rt]<b[rt<<1])
{
b[rt<<1]=a[rt];
}
if(a[rt]<a[rt<<1])
{
b[rt<<1]=a[rt<<1];
a[rt<<1]=a[rt];
}
if(a[rt]>=a[rt<<1|1]&&a[rt]<b[rt<<1|1])
{
b[rt<<1|1]=a[rt];
}
if(a[rt]<a[rt<<1|1])
{
b[rt<<1|1]=a[rt<<1|1];
a[rt<<1|1]=a[rt];
}
a[rt]=9999999;
}
//printf("%d %d ++%d++\n",a[rt<<1],b[rt<<1],rt<<1);
}
void build(int l,int r,int rt)
{
a[rt]=b[rt]=9999999;
if(l==r)
{
a[rt]=b[rt]=l;
return;
}
build(lson);
build(rson);
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(l>=L&&r<=R)
{
int x=val;
if(b[rt]>x&&x>a[rt])
{
b[rt]=x;
}
if(x<b[rt])
{
b[rt]=a[rt];
a[rt]=x;
}
return;
}
pushdown(rt);
if(L<=mid)  update(L,R,val,lson);
if(R>mid)  update(L,R,val,rson);
}
int query(int pos,int l,int r,int rt)
{
//printf("%d %d %d %d %d\n",a[rt],b[rt],l,r,rt);
if(l==r)
{
return b[rt];
}
pushdown(rt);
if(pos<=mid)  return query(pos,lson);
else return query(pos,rson);
}
int main()
{
int i,j,k,ca=1,q;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
int x,y;
build(root);
for(i=0;i<m;i++)
{
scanf("%d%d",&y,&x);
update(x,y,x,root);    //记录次小x
}
while(q--)
{
scanf("%d",&x);
printf("%d\n",x-query(x,root));
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: