HDU5032 Always Cook Mushroom(树状数组&&离线)

树状数组+询问离线。一个优化是需要的,就是先对1000*1000个点先排序,而不是每次都生成这1000*1000个点然后和询问一起排序,那样会tle.

#include <iostream>

#include <cstring>

#include <string>

#include <vector>

#include <cstdio>

#include <algorithm>

#include <cmath>

using namespace std;



#define maxn 1200

#define ll long long



ll A,B;



struct Node

{

    ll a,b;

    int t;

    ll v;

    int id;

    bool operator < (const Node& y) const{

        if(b*y.a!=a*y.b) return b*y.a<a*y.b;

        else return t<y.t;

    }

}x[120000],y[1005000];



int tot,tot2;



ll ans[200000];



ll bit[maxn];



void add(int i,ll v){

    while(i<=1000){

        bit[i]+=v;

        i+=i&(-i);

    }

}



ll sum(int i){

    ll ret=0;

    while(i>0){

        ret+=bit[i];

        i-=i&(-i);

    }

    return ret;

}



int main()

{

    int T;cin>>T;int ca=0;

    tot2=0;

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

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

            y[tot2].a=i;y[tot2].b=j;

            y[tot2++].t=1;

        }

    }

    sort(y,y+tot2);

    while(T--){

        scanf("%I64d%I64d",&A,&B);

        tot=0;

        int m;scanf("%d",&m);

        int ai,bi,xi;

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

            scanf("%d%d%d",&ai,&bi,&xi);

            x[tot].a=ai;

            x[tot].b=bi;

            x[tot].id=i;

            x[tot].t=2;

            x[tot++].v=xi;

        }



        sort(x,x+tot);

        memset(bit,0,sizeof(bit));

        int id=0;

        for(int i=0;i<tot;++i){

            while(id<tot2&&y[id]<x[i]){

                add(y[id].a,(y[id].a+A)*(y[id].b+B));

                ++id;

            }

            ans[x[i].id]=sum(x[i].v);

        }

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

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

            printf("%I64d\n",ans[i]);

        }

    }

    return 0;

}

 

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