HDU1806Frequent values

调了一晚上1255矩形面积的那个代码,调不通了,跟之前拿个赛区的题目相似,一直想着先把矩形总面积算出来,减掉所围成的总面积便是结果,后来发现好像不是这么回事,重复覆盖的曲剧超过两次的不被计入在我要减去的面积中,这样就导致我的结果肯定会大于正确答案,按照这个思路继续下去的话,就是要标记覆盖次数了,调出来,不存在的。。。画个图就很明白了,思路很清晰的跑偏了。。。求面积总和的代码不再发了,(见9.24网络赛,Overlapping Rectangles == hdu1542 Atlantis),只不过是数据类型不同,这里补发一个前些天做过的题目。

 

Frequent values

Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)

Total Submission(s) : 24   Accepted Submission(s) : 10

Problem Description

You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.

 

 

Input

<p>The input consists of several test cases. Each test case starts with a line containing two integers <strong>n</strong> and <strong>q</strong> (<i>1 ≤ n, q ≤ 100000</i>). The next line contains <strong>n</strong> integers <strong>a<sub>1</sub> , ... , a<sub>n</sub></strong> (<i>-100000 ≤ a<sub>i</sub> ≤ 100000</i>, for each <i>i ∈ {1, ..., n}</i>) separated by spaces. You can assume that for each <i>i ∈ {1, ..., n-1}: a<sub>i</sub> ≤ a<sub>i+1</sub></i>. The following <strong>q</strong> lines contain one query each, consisting of two integers <strong>i</strong> and <strong>j</strong> (<i>1 ≤ i ≤ j ≤ n</i>), which indicate the boundary indices for the <br>query.</p><p>The last test case is followed by a line containing a single <i>0</i>.</p>

 

 

Output

<p>For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.</p>

 

 

Sample Input

 

10 3 -1 -1 1 1 1 1 3 10 10 10 2 3 1 10 5 10 0

 

 

Sample Output

 

1 4 3

题意:给出有n个数字非降序的数列,m次询问,问[a,b]区间内出现次数最多的次数是多少。。。翻译的怎么这么蹩脚呢

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define N 100010
using namespace std;
struct node
{
    int l,r;
    int val;
}tree[N<<2];
struct Node
{
    int s,e;
}cnt[N];
int ma[N],vis[N];
int max(int a,int b)
{
    return a>b?a:b;
}
void pushup(int rt)
{
    tree[rt].val=max(tree[rt<<1].val,tree[rt<<1|1].val);
}
void build(int l,int r,int rt)
{
    tree[rt].l=l;
    tree[rt].r=r;
    int mid=(l+r)>>1;
    if(l==r)
    {
        tree[rt].val=cnt[l].e-cnt[l].s+1;
        return;
    }
    build(lson);
    build(rson);
    pushup(rt);
}
int query(int l,int r,int rt)
{
    if(l<=tree[rt].l&&tree[rt].r<=r)
        return tree[rt].val;
    int mid=(tree[rt].l+tree[rt].r)>>1;
    if(l>mid)
        return query(l,r,rt<<1|1);
    else if(r<=mid)
        return query(l,r,rt<<1);
    else
        return max(query(lson),query(rson));
}
int main()
{
    int n,m;
    while(cin>>n)
    {
        if(n==0)
            break;
        cin>>m;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
            scanf("%d",&ma[i]);
        vis[1]=1;
        cnt[1].s=1;
        if(n==1)
        cnt[1].e=1;
        int num=1;
        for(int i=2;i<=n;i++)
        {
            if(ma[i]!=ma[i-1])
            {
                cnt[num].e=i-1;
                num++;
                cnt[num].s=i;
                vis[i]=num;
            }
            else
                vis[i]=num;
        }
        vis[n]=num;
        cnt[num].e=n;
        build(1,num,1);
        int a,b,ans;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            if(vis[a]==vis[b])
            {
                ans=b-a+1;
            }
            else if(vis[b]-vis[a]==1)
            {
                ans=max(cnt[vis[a]].e-a+1,b-cnt[vis[b]].s+1);
            }
            else
            {
                ans=max(cnt[vis[a]].e-a+1,b-cnt[vis[b]].s+1);
                ans=max(ans,query(vis[a]+1,vis[b]-1,1));
            }
            cout<<ans<<endl;
        }
    }
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值