USACO 3.1 Shaping Regions

64 篇文章 0 订阅
54 篇文章 0 订阅

由于数据规模实在大的BT,所以只能使用离散化构线段树...

首先对x离散化,然后构造一个一维的线段树,并重复操作,最后统计该X区间内所有颜色映射在Y上的长度,就可以得到这个区间内的每种颜色的面积,至于颜色1,我是在最后把n*m减去所有颜色的面积得到的。。

最后一个BT数据跑了1。3XS才过。。。瀑布汗....

 

 

 

USER: A e [chenh193]
TASK: rect1
LANG: C++

Compiling...
Compile: OK

Executing...
Test 1: TEST OK [0.032 secs, 3148 KB]
Test 2: TEST OK [0.000 secs, 3148 KB]
Test 3: TEST OK [0.000 secs, 3144 KB]
Test 4: TEST OK [0.022 secs, 3144 KB]
Test 5: TEST OK [0.022 secs, 3144 KB]
Test 6: TEST OK [0.011 secs, 3148 KB]
Test 7: TEST OK [0.011 secs, 3144 KB]
Test 8: TEST OK [0.011 secs, 3148 KB]
Test 9: TEST OK [0.011 secs, 3144 KB]
Test 10: TEST OK [0.011 secs, 3144 KB]
Test 11: TEST OK [1.382 secs, 3144 KB]

All tests OK.

 

/*
ID: chenh193
PROG: rect1
LANG: C++
*/
#include<iostream>
#include<algorithm>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
struct Seg
{
    int l,r,c;
}seg[32767];
int cnt[2501],ans[2501];
void mkseg(int l,int r,int x)
{
    seg[x].l=l;
    seg[x].r=r;
    seg[x].c=-1;
    if(l==r-1)return;
    int mid=(l+r)/2;
    mkseg(l,mid,2*x);
    mkseg(mid,r,2*x+1);
}
void ins(int l,int r,int c,int x)
{
    if(seg[x].l+1!=seg[x].r)
    {
        if(seg[x].c!=-1)
            seg[2*x].c=seg[2*x+1].c=seg[x].c,seg[x].c=-1;
    }
    if(l<=seg[x].l&&seg[x].r<=r)
    {
        seg[x].c=c;
        return;
    }
    int mid=(seg[x].l+seg[x].r)/2;
    if(l>=mid)
        ins(l,r,c,2*x+1);
    else
        if(r<=mid)
            ins(l,r,c,2*x);
        else
            ins(l,mid,c,2*x),ins(mid,r,c,2*x+1);
}
void pre(int x)
{
    if(seg[x].c!=-1)
    {
        cnt[seg[x].c]+=(seg[x].r-seg[x].l);
        return;
    }
    if(seg[x].l+1==seg[x].r)return;
    pre(2*x);
    pre(2*x+1);
}
int X[2002],len=0;
struct OP
{
    int xl,xh,yl,yh,c;
}op[1001];
int main()
{
    int n,i,j,k,m,t,YL=0;
    //OPEN
     freopen("rect1.out","w",stdout);
     freopen("rect1.in","r",stdin);
    scanf("%d%d%d",&n,&m,&t);
    for(i=0;i<t;i++)
    {
        scanf("%d%d%d%d%d",&op[i].xl,&op[i].yl,&op[i].xh,&op[i].yh,&op[i].c);
        X[len]=op[i].xl;
        X[len+1]=op[i].xh;
        if(op[i].yh>YL)YL=op[i].yh;
        len+=2;
    }
    sort(X,X+len);
    for(i=0;i<len-1;i++)
    {
        if(X[i]==X[i+1])continue;
        mkseg(0,YL,1);
        memset(cnt,0,sizeof(cnt));
        for(j=0;j<t;j++)
        {
            if(op[j].xl<=X[i]&&op[j].xh>=X[i+1])
            {
                ins(op[j].yl,op[j].yh,op[j].c,1);
            }
        }
        pre(1);
        for(j=2;j<=2500;j++)
        {
            //printf("[%d,%d]==> cnt[%d]=%d/n",X[i],X[i+1],j,cnt[j]);
            ans[j]+=(X[i+1]-X[i])*cnt[j];
        }
        //puts("");
    }
    ans[1]=m*n;
    for(i=2;i<=2500;i++)ans[1]-=ans[i];
    for(i=1;i<=2500;i++)if(ans[i])printf("%d %d/n",i,ans[i]);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值