2016多校联合训练#10
HDU 5862 Counting Intersections
线段树,扫描线
题意
给一些平行与坐标轴的线段,求交点个数。线段之间没有公共端点,没有重叠,没有长度0的。
思路
扫描线。。线段树维护。。我是不会树状数组。。。
保存竖线,保存横线的端点,记录左右。遇到左端点右端点更新线段树,遇到竖线查询。
但是我为什么tmd过不去。。。。
代码
WA的代码!!!以后再改吧
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <iomanip>
#include <string>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN=100005;
const int oo=1000000007;
typedef long long int LL;
struct Tree{
int sum;
}tree[MAXN<<2];
struct Linev{
int d,u;
int x;
int sign;
bool operator < (const Linev &l)const
{
return x<l.x;
}
}v[MAXN<<1];
int h[MAXN<<1];
void PushUP(int rt)
{
tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
}
void build(int l,int r,int rt)
{
if(l==r)
{
tree[rt].sum=0;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUP(rt);
}
void update(int x,int p,int l,int r,int rt)
{
if(l==r)
{
tree[rt].sum+=p;
return;
}
int m=(l+r)>>1;
if(x<=m) update(x,p,lson);
if(x>m) update(x,p,rson);
PushUP(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return (LL)tree[rt].sum;
}
int m=(r+l)>>1;
LL res=0;
if(L<=m) res+=(LL)query(L,R,lson);
if(m<R) res+=(LL)query(L,R,rson);
return res;
}
int main()
{
freopen("1006.in","r",stdin);
freopen("out.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
memset(v,0x3f,sizeof(v));
memset(h,0x3f,sizeof(h));
int n;
scanf("%d",&n);
int cnth=0;
int cntv=0;
for(int i=0;i<n;i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
if(a==c)
{
if(b<d) swap(b,d);
v[cntv].d=d;v[cntv].u=b;v[cntv].x=a;v[cntv++].sign=0;
h[cnth++]=b;h[cnth++]=d;
}
else if(b==d)
{
if(a>c) swap(a,c);
v[cntv].d=b;v[cntv].u=b;v[cntv].x=a;v[cntv++].sign=1;
v[cntv].d=b;v[cntv].u=b;v[cntv].x=c;v[cntv++].sign=-1;
h[cnth++]=b;
}
}
sort(v,v+cntv);
sort(h,h+cnth);
int m=1;
for(int i=1;i<cnth;i++)
{
if(h[i]!=h[i-1])
{
h[m++]=h[i];
}
}
build(1,m,1);
LL res=0;
for(int i=0;i<cntv;i++)
{
if(v[i].sign==1)
{
int y=lower_bound(h,h+m,v[i].d)-h+1;
update(y,1,1,m,1);
}
else if(v[i].sign==-1)
{
int y=lower_bound(h,h+m,v[i].d)-h+1;
update(y,-1,1,m,1);
}
else
{
int l=lower_bound(h,h+m,v[i].d)-h+1;
int r=lower_bound(h,h+m,v[i].u)-h+1;
if(l<=r) res+=(LL)query(l,r,1,m,1);
}
}
printf("%lld\n",res);
}
return 0;
}