SPOJ

来源:互联网 发布:游戏网络推广员 编辑:程序博客网 时间:2024/06/05 06:27

                                ADAFIELD - Ada and Field

 这个题,如果用一个字来形容的话:-----------------------------------------------嗯!

 题意:n*m的空白矩形坐落在XY轴,Q次操作,每次可以在y轴或x轴的矩形区域内画一条直线,是直线啊。问每次操作后最大的矩形面积多大。

  对于思路我只能拍手称赞了,一开始想不到怎么优化,想着用优先队列或set来存当前边的最大值,但是更新的时候却 无法实时更新。赛后看其他选手的代码才突然想到可以用map的键值来排序,每次插入一个数只需断一条边加两条边,各种操作的的复杂度都是log。

int main(){    int t,Q,k;    ll n,m,p,maxx[2];    scanf("%d",&t);    while(t--)    {        scanf("%I64d%I64d%d",&n,&m,&Q);        set<ll>q[2];        set<ll>::iterator it,lp,rp;        map<ll,ll,greater<ll> >qq[2];        q[0].insert(0),q[0].insert(n);//0表示竖直方向插入        q[1].insert(0),q[1].insert(m);//1表示水平方向插入        ++qq[0][n],++qq[1][m];        maxx[0]=n,maxx[1]=m;        while(Q--)        {            scanf("%d%I64d",&k,&p);            if(q[k].find(p)==q[k].end())            {                q[k].insert(p);                it=q[k].lower_bound(p);                lp=rp=it;                rp++;//后一个的值                if(lp!=q[k].begin()) lp--;//前一个的值                if(rp==q[k].end()) rp--;                ++qq[k][*rp-*it];//更新                ++qq[k][*it-*lp];                --qq[k][*rp-*lp];//删去原来的                if(!qq[k][*rp-*lp]) qq[k].erase(*rp-*lp);//特别需要注意的地方                maxx[k]=qq[k].begin()->first;            }            cout<<maxx[0]*maxx[1]<<endl;        }    }    return 0;}


ADAFIELD - Ada and Field
0 0
原创粉丝点击