HDOJ  4325  Flowers

来源:互联网 发布:java 如何使用瞬态值 编辑:程序博客网 时间:2024/05/29 23:44

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4325

题目自解:将开花时间和闭花时间进行排序,

某时刻开花的数减去花谢的数就是正在盛开的花的数目,用二分法查找

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int a[100005],b[1000005];
int see[100005][2];
int n,m;
int Find(int time)
{
    intlow=0,high=n-1,mid;
   while(low<=high)
    {
       mid=(low+high)/2;
       if(a[mid]==time)
       {
           while(mid<n&&a[++mid]==time);
           return mid;
       }
       if(a[mid]<time)
           low=mid+1;
       else
           high=mid-1;
    }
    returnlow;
}
int Search(int time)
{
    intlow=0,high=n-1,mid;
   while(low<=high)
    {
       mid=(low+high)/2;
       if(b[mid]==time)
       {
           while(mid>=0&&b[--mid]==time);
           return mid+1;
       }
       if(b[mid]<time)
           low=mid+1;
       else
           high=mid-1;
    }
    returnlow;
}
int cmp( const void *a , const void *b )
{
       return *(int *)a - *(int *)b;
}
int main()
{
    inth=1,t,i,j;
   scanf("%d",&t);
   while(t--)
    {
       memset(see,0,sizeof(see));
       memset(a,0,sizeof(a));
       memset(b,0,sizeof(b));
       scanf("%d%d",&n,&m);
       for(i=0;i<n;i++)
           scanf("%d%d",&a[i],&b[i]);
       printf("Case #%d:\n",h++);
       qsort(a,n,sizeof(a[0]),cmp);
       qsort(b,n,sizeof(b[0]),cmp);
       for(i=0;i<m;i++)
           scanf("%d",&see[i][0]);
       for(j=0;j<m;j++)
           see[j][1]=Find(see[j][0])-Search(see[j][0]);
       for(i=0;i<m;i++)
           printf("%d\n",see[i][1]);
    }
    return0;
}
还有题解给的是:这个题就是比较裸的区间更新,单点查询的线段树。一开始需要把要查询的点和花开的时间和花谢的时间一起离散化了,这样查询的时候就方便多了。

#include<cstdio>
#include<map>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=100010;
struct eee{int st,end;}ee[N];
int foruse[N];
int nt[N];
int size;
int getvalue(int i)
{
    intl=0,r=size;
   while(l+1<r)
    {
       int mid=(r+l)/2;
       if(foruse[mid]<=i)
       {
           l=mid;
       }
       else r=mid;
    }
    returnr;
}

int lowbit(int num)
{
    returnnum&(num^(num-1));
}

void add(int num,int pos)
{
   while(pos<N)
    {
       nt[pos]+=num;
       pos+=lowbit(pos);
    }
}

int get(int pos)
{
    intret=0;
   while(pos>0)
    {
       ret+=nt[pos];
       pos-=lowbit(pos);
    }
    returnret;
}

int main()
{
   freopen("data.in","r",stdin);
   freopen("data3.out","w",stdout);
    intti;
   scanf("%d",&ti);
    for(intca=1;ca<=ti;ca++)
    {
       int n,m;
       int cnt=0;
       int *it;
       scanf("%d%d",&n,&m);
       for(int i=0;i<n;i++)
       {
           int t1,t2;
           scanf("%d%d",&t1,&t2);
           ee[i].st=t1;
           ee[i].end=t2+1;
           foruse[2*i+1]=t1;
           foruse[2*i+2]=t2+1;
       }
       sort(foruse+1,foruse+2*n+1);
       it=unique(foruse+1,foruse+2*n+1);
       size=it-foruse;
       foruse[0]=0;foruse[size]=1e9+1;
       memset(nt,0,sizeof(nt));
       for(int i=0;i<n;i++)
       {
           add(1,getvalue(ee[i].st));
           add(-1,getvalue(ee[i].end));
       }
       printf("Case #%d:\n",ca);
       for(int i=0;i<m;i++)
       {
           int t;
           scanf("%d",&t);
           printf("%d\n",get(getvalue(t)));
       }
    }
    return0;
}
因为我的线段树还没有学习呢,所以感觉第一种比较简单,好理解

0 0
原创粉丝点击