Sicily9564

用线段树做还是超时,百度了一下发现有简便算法。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <deque>
using namespace std;

    int xmin[1000005]={0};
    int xmax[1000005]={0};
    int ymin[1000005]={0};
    int ymax[1000005]={0};
int main()
{
    int m;
    int i,j;
    int x,y;
    scanf("%d",&m);

    for (i=0;i<=m-1;i++)
    {
        int maxx=0,maxy=0;
        int minx=2000000000,miny=2000000000;
        for (j=1;j<=3;j++)
        {
            scanf("%d %d",&x,&y);
            if (x>maxx)
                maxx=x;
            if (x<minx)
                minx=x;
            if (y>maxy)
                maxy=y;
            if (y<miny)
                miny=y;
        }
        //printf("maxx%d maxy%d minx%d miny%d\n",maxx,maxy,minx,miny);
        /*for (j=minx+1;j<maxx;j++)
            hashx[j]++;
        for (j=miny+1;j<maxy;j++)
            hashy[j]++;*/
        xmin[minx]++;
        xmax[maxx]++;
        ymin[miny]++;
        ymax[maxy]++;
    }

    for (i=1;i<=1000000;i++)
    {
    	xmin[i]+=xmin[i-1];
    	xmax[i]+=xmax[i-1];
    	ymin[i]+=ymin[i-1];
    	ymax[i]+=ymax[i-1];
    }


    char s1[5],s2[5];
    int num;
    scanf("%d",&m);
    for (i=0;i<=m-1;i++)
    {
        scanf("%s %s %d",s1,s2,&num);
        if (s1[0]=='x')
            printf("%d\n",xmin[num-1]-xmax[num]);
        else
            printf("%d\n",ymin[num-1]-ymax[num]);
    }
    return 0;
}

线段树:

Lazy_Tag

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <deque>
using namespace std;

struct CNode
{
  int L,R;
  int data;
  CNode *pLeft,*pRight;
  bool is_same;
};

CNode Treex[2000005];
CNode Treey[2000005];
int nCountx=0;
int nCounty=0;

void BuildTree(CNode *pRoot,int L,int R,CNode *Tree,int &nCount)
{
    pRoot->L=L;
    pRoot->R=R;
    pRoot->data=0;
    pRoot->is_same=true;
    if (L==R)
        return;
    nCount++;
    pRoot->pLeft=Tree+nCount;
    nCount++;
    pRoot->pRight=Tree+nCount;
    BuildTree(pRoot->pLeft,L,(L+R)/2,Tree,nCount);
    BuildTree(pRoot->pRight,(L+R)/2+1,R,Tree,nCount);
}

void Insert(CNode *pRoot,int l,int r)
{
    if (l>r)
        return;
    int mid=(pRoot->L+pRoot->R)/2;

        if (l==pRoot->L && r==pRoot->R && pRoot->is_same)
        {
          pRoot->data++;
          return;
        }
        else
        {
            if (pRoot->is_same)
            {
                pRoot->is_same=false;
              pRoot->pLeft->data=pRoot->data;
              pRoot->pRight->data=pRoot->data;
            }
            if (l<=mid && r<=mid)
                Insert(pRoot->pLeft,l,r);
            else if (l<=mid && r>mid)
            {
                Insert(pRoot->pLeft,l,mid);
                Insert(pRoot->pRight,mid+1,r);
            }
            else
                Insert(pRoot->pRight,l,r);
        }

}

int Query(CNode *pRoot,int pos)
{
    if (pos<=pRoot->R && pos>=pRoot->L && pRoot->is_same)
        return pRoot->data;
    if (pos<=(pRoot->L+pRoot->R)/2)
        return Query(pRoot->pLeft,pos);
    else
        return Query(pRoot->pRight,pos);
}

int main()
{
    int m;
    int i,j;
    int x,y;
    scanf("%d",&m);
    CNode *pRootx=Treex;
    CNode *pRooty=Treey;
    BuildTree(pRootx,0,1000000,Treex,nCountx);
    BuildTree(pRooty,0,1000000,Treey,nCounty);
    for (i=0;i<=m-1;i++)
    {
        int maxx=0,maxy=0;
        int minx=2000000000,miny=2000000000;
        for (j=1;j<=3;j++)
        {
            scanf("%d %d",&x,&y);
            if (x>maxx)
                maxx=x;
            if (x<minx)
                minx=x;
            if (y>maxy)
                maxy=y;
            if (y<miny)
                miny=y;
        }
        //printf("maxx%d maxy%d minx%d miny%d\n",maxx,maxy,minx,miny);
        /*for (j=minx+1;j<maxx;j++)
            hashx[j]++;
        for (j=miny+1;j<maxy;j++)
            hashy[j]++;*/
        Insert(pRootx,minx+1,maxx-1);
        Insert(pRooty,miny+1,maxy-1);
    }

    char s1[5],s2[5];
    int num;
    scanf("%d",&m);
    for (i=0;i<=m-1;i++)
    {
        scanf("%s %s %d",s1,s2,&num);
        if (s1[0]=='x')
            printf("%d\n",Query(pRootx,num));
        else
            printf("%d\n",Query(pRooty,num));
    }
    return 0;
}               


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值