SPOJ Ada and Field

题目链接:http://www.spoj.com/problems/ADAFIELD/en/

ADAFIELD - Ada and Field



Ada the Ladybug owns a beautiful field where she grows vegetables. She often visits local Farmers Market, where se buys new seeds. Since two types of vegetable can't share same field, she always divide the field, by either vertical or horizontal line (she is very precise, so the width of line is negligible). Since she visits Farmers Market almost every day, she has already made a lot of such lines, so she needs your help with finding out the area of biggest field.

Input

The first line will contain 0 < T ≤ 200, the number of test-cases.

Then T test-cases follow, each beginning with three integers 1 ≤ N,M ≤ 2*1091 ≤ Q ≤ 105, top right corner of field (field goes from [0,0] to [N,M]) and number of field divisions.

Afterward Q lines follows:

0 x (0 ≤ x ≤ N), meaning that line was made vertically, on coordinate x

1 y (0 ≤ y ≤ M), meaning that line was made horizontally, on coordinate y

Sum of over all test-cases won't exceed 106

Output

Print Q lines, the area of biggest field after each line was made.

Example Input

2
10 10 5
0 5
0 8
1 1
1 9
1 5
10 10 5
0 5
1 4
1 6
1 8
0 5

Example Output

50
50
45
40
20
50
30
20
20
20

题意是给一个n*m的矩形,然后有Q组操作。每次操作有两种类型,操作0:给出x0,平行y轴,在x=x0处切割一条线,同时输出当前切了之后剩下的矩形的最大的那个。操作1:给出y0,平行x轴,在y = y0处切割一条线,同时输出当前切割之后剩下的矩形中最大。


分析一下,每切一条线,其实只会影响到离他最近的左右两条线,当前最大的矩形,是x轴上间隔的最大值乘上y轴上间隔的最大值。那么可以对x轴y轴各建一个set,然后每次操作找到他左右最近的两条线,然后需要再建两个multiset分别维护x轴和y轴上的间隔既可以;

#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<time.h>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<iostream>
using namespace std;
#define  LONG long long
const LONG   INF=0x3f3f3f3f;
const LONG  MOD=1e9+61;
const double PI=acos(-1.0);
#define clrI(x) memset(x,-1,sizeof(x))
#define clr0(x) memset(x,0,sizeof x)
#define clr1(x) memset(x,INF,sizeof x)
#define clr2(x) memset(x,-INF,sizeof x)
#define EPS 1e-10
#define lson  l , mid , rt<< 1
#define rson  mid + 1 ,r , (rt<<1)+1
#define root 1, m , 1
multiset<LONG > x;
multiset<LONG > y;
set <LONG > xx ;
set <LONG > yy ;
void Init(LONG n , LONG m )
{
        x.clear() ;
        y.clear() ;
        xx.clear() ;
        yy.clear() ;
        x.insert( n ) ;
        y.insert( m ) ;
        xx.insert( 0 ) ;
        xx.insert( n ) ;
        yy.insert( 0 ) ;
        yy.insert( m ) ;
}
int  main()
{
    LONG T;
    cin>>T;
    while(T--)
    {
        LONG n , m , Q;
        cin>>n>>m>>Q;
        Init( n , m ) ;
        set<LONG>::iterator it ;
        multiset<LONG>::iterator itt ;
        LONG op ;
        LONG tmp ;
        for(LONG i = 1;i <= Q ;++ i)
        {
            scanf("%lld%lld",&op,&tmp) ;
            if(op == 0 )
            {
                it = xx.lower_bound(tmp) ;
                if(xx.find(tmp) == xx.end())
                {
                    LONG t2 = *it ;
                    it -- ;
                    LONG t1 = *it ;
                    LONG num = t2 - t1 ;
                    itt = x.find( num ) ;
                    x.erase(itt) ;
                    x.insert( t2 - tmp )  ;
                    x.insert( tmp - t1 ) ;
                }
                itt = x.end() ;
                itt -- ;
                LONG ans = (LONG)*itt ;
                itt = y.end() ;
                itt -- ;
                ans *= *itt ;
                printf("%lld\n",ans) ;
                xx.insert( tmp ) ;
            }
            else
            {
                it = yy.lower_bound( tmp ) ;
                if( yy.find(tmp) == yy.end())
                {
                    LONG t2 = *it ;
                    it -- ;
                    LONG t1 = *it ;
                    LONG num = t2 - t1 ;
                    itt = y.find( num ) ;
                    y.erase( itt ) ;
                    y.insert( t2 - tmp) ;
                    y.insert( tmp - t1) ;
                }
                itt = y.end() ;
                itt -- ;
                LONG ans = *itt ;
                itt = x.end() ;
                itt -- ;
                ans *= *itt ;
                printf("%lld\n",ans );
                yy.insert( tmp ) ;
            }
        }
        x.clear() ;
        y.clear() ;
        xx.clear() ;
        yy.clear() ;
    }
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值