这道题本身并不难,也是线段树类型的,固定了水平面,只需要一维线段树(也只会一维 = =)线段树插入高度作为点的权值。。。
//1900ms
#include <stdio.h>
#include <stdlib.h>
#define N 40001
int a[N][3];
int top=-1;
int set[2*N];
int settop=-1;
int rset[2*N];
int rsettop=-1;
long long sum=0;
struct st{
int a,b;
int ld,rd;
int high;
int mid;
}tree[4*N];
void build(int a,int b)
{
int mid;
int top2;
tree[++top].a=a;
tree[top].b=b;
tree[top].high=0;
if(a==b-1) {
tree[top].ld=-1;
tree[top].rd=-1;
return ;
}
tree[top].mid=mid=(a+b)/2;
top2=top;
tree[top2].ld=top+1;
build(a,mid);
tree[top2].rd=top+1;
build(mid,b);
}
void insert(int p,int q,int c,int k)
{
if(tree[tree[k].rd].high==tree[tree[k].ld].high && tree[tree[k].ld].high>tree[k].high )
tree[k].high=tree[tree[k].ld].high;
if(rset[tree[k].a]==p && rset[tree[k].b]==q && tree[k].high!=-1) {tree[k].high=tree[k].high>c?tree[k].high:c; return ;}
if(tree[k].high>0)
{
insert(rset[tree[k].a],rset[tree[k].mid],tree[k].high,tree[k].ld);
insert(rset[tree[k].mid],rset[tree[k].b],tree[k].high,tree[k].rd);
}
tree[k].high=-1;
if(p<rset[tree[k].mid] && q>rset[tree[k].mid])
{insert(p,rset[tree[k].mid],c,tree[k].ld);insert(rset[tree[k].mid],q,c,tree[k].rd);}
else if(p<rset[tree[k].mid]) insert(p,q,c,tree[k].ld);
else insert(p,q,c,tree[k].rd);
}
void dfs(int k)
{
if(!tree[k].high) return ;
if(tree[k].high!=-1)
{
sum+=(rset[tree[k].b]-rset[tree[k].a])*(long long)tree[k].high;
}
else
{
dfs(tree[k].ld);
dfs(tree[k].rd);
}
}
int cmp(const void *a, const void *b)
{
return(*(int *)a-*(int *)b);
}
int main()
{
int i;
int n;
int p,q,c;
int temp;
// freopen("1.txt", "r", stdin);
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
set[++settop]=a[i][0];
set[++settop]=a[i][1];
}
qsort(set,2*n,sizeof(set[0]),cmp);
rset[++rsettop]=set[0];
for(i=1;i<=settop;i++)
{
if(set[i]!=set[i-1])
rset[++rsettop]=set[i];
}
build(0,rsettop);
for(i=0;i<n;i++)
{
insert(a[i][0],a[i][1],a[i][2],0);
}
dfs(0);
printf("%lld\n",sum);
return 0;
}
这道题很强大,这样写很浪费时间,关键在于面积只需要最后才统计,所以插入过程中并不需要维护线段树,所以化简吧~~~
void insert(int p,int q,int c,int k)
{
if(rset[tree[k].a]>=p && rset[tree[k].b]<=q)
{
tree[k].high=tree[k].high>c?tree[k].high:c;
return ;
}
if(p<rset[tree[k].mid]) insert(p,q,c,tree[k].ld);
if(q>rset[tree[k].mid]) insert(p,q,c,tree[k].rd);
}
void dfs(int k)
{
if(tree[k].b-tree[k].a==1)
{
sum+=(rset[tree[k].b]-rset[tree[k].a])*(long long)tree[k].high;
return ;
}
tree[tree[k].ld].high=tree[k].high>tree[tree[k].ld].high?tree[k].high:tree[tree[k].ld].high;
tree[tree[k].rd].high=tree[k].high>tree[tree[k].rd].high?tree[k].high:tree[tree[k].rd].high;
dfs(tree[k].ld);
dfs(tree[k].rd);
}
速度达到180ms了~~~
浙公网安备 33010602011771号