HDU - 5032 Always Cook Mushroom(极角排序 + 树状数组离线操作)

 

HDU - 5032 Always Cook Mushroom(极角排序 + 树状数组离线操作)

 

网络赛的一题,没有看过题目,看了郏老大博客来A这题。

 

题意:

对于一个1000*1000的Mushroom,

给定一个斜率和一个x,求由斜率和x所对应的直线构成的三角形内蘑菇的总值。

每个点的对应的值为(x+A)(y+B)

 

分析:

这东西二维的啊,,没思路。看了题解知道了,转化为一维,并离线处理

即极角对应的射线,从0°开始扫到90°

首先预处理,对所有的点按照斜率升序排序。

全部读取查询操作也进行斜率排序,并用Hash记录index

最后离线操作一并输出。

 

代码,加了个输入输出外挂,根本停不下来

/* ***********************************************

ID      : whiteblock63

LANG    : G++

PROG    : Hdu - 5032 Always Cook Mushroom

DATE    : 2014-10-08 19:02:53

************************************************ */



#include <cstdio>

#include <cstring>

#include <iostream>

#include <algorithm>

#define CLR( a, b )        memset( a, b, sizeof(a) )

typedef long long LL;

typedef unsigned long long ULL;



const int MAXN  = 1e3 + 5;

const int MAXM  = 1e5 + 5;

using namespace std;



LL bit[MAXN];

LL ans[MAXM], Hash[MAXM];



void scan( LL &x )

{

    char c;

    while( c = getchar(), c < '0' || c > '9' );

    x = c - '0';

    while( c = getchar(), c >= '0' && c <= '9' ) x = x*10 + c - '0';

}



void out( LL x )

{

    if( x > 9 ) out( x/10 );

    putchar( x%10 + '0' );

}



inline int lowbit( int x )

{

    return x & -x;

}



void add( int x, int val )

{

    while( x <= 1000 )

    {

        bit[x] += val;

        x += lowbit( x );

    }

}



LL sum( int x )

{

    LL ret = 0;

    while( x > 0 )

    {

        ret += bit[x];

        x -= lowbit( x );

    }

    return ret;

}



struct Point

{

    LL a, b;

    double s;

}P[MAXN * MAXN];



struct Query

{

    LL a, b, x, id;

    double s;

}Q[MAXM];





bool cmp1( Point x, Point y )

{

    return x.s < y.s;

}



bool cmp2( Query x, Query y )

{

    if( x.s == y.s )    return x.x < y.x;

    return x.s < y.s;

}



void Orz()

{

    int cnt = 0, m;

    int A, B;

    for( int i = 1; i <= 1000; ++i )

    {

        for( int j = 1; j <= 1000; ++j )

        {

            P[cnt].a = i;

            P[cnt].b = j;

            P[cnt++].s = 1.0*j / i;

        }

    }

    sort( P, P + cnt, cmp1 );



    int cas = 0, t = 0;

    

    scan ( t );

    while( t-- )

    {

        CLR( bit, 0 );

        scan( A ), scan( B ), scan( m ); 

        for( int i = 0; i < m; ++i )

        {

            scan( Q[i].a ), scan( Q[i].b ), scan( Q[i].x );

            Q[i].s = 1.0*Q[i].b / Q[i].a;

            Q[i].id = i;

        }



        sort( Q, Q + m, cmp2 );

        for( int i = 0; i < m; ++i )

        {

            Hash[Q[i].id] = i;

         }

        cnt = 0;

        printf( "Case #%d:\n", ++cas );

        for( int i = 0; i < m; ++i )

        {

            while( P[cnt].s <= Q[i].s )

            {

                add( P[cnt].a, (P[cnt].a + A) * (P[cnt].b + B) );

                cnt++;

            }

            ans[i] = sum( Q[i].x );

        }

        for( int i = 0; i < m; ++i )

            out( ans[Hash[i]] );

    }

}



int main()

{

    Orz();

    return 0;

}
代码君

 

你可能感兴趣的:(树状数组)