poj 3145 Harmony Forever(线段树)

本文探讨了在解决复杂问题时如何使用高效算法提高效率,包括排序算法、动态规划、哈希算法等核心概念和应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


poj 3145 Harmony Forever


奇葩怪异吐血题,无力多说、、、


#include<stdio.h>
#include<string.h>
#define MAXN 600000
#define INF 2000000
#define lch p<<1
#define rch p<<1|1
#define mid (t[p].l+t[p].r)>>1
struct node
{
    int l,r;
    int val;
}t[MAXN<<2];
void construct(int l,int r,int p)
{
    t[p].l=l,t[p].r=r,t[p].val=INF;
    if(l==r) return ;
    int m=mid;
    construct(l,m,lch);
    construct(m+1,r,rch);
}
int min(int a,int b) {return a<b?a:b;}
void modify(int x,int p)
{
    if(t[p].l==t[p].r)
    {
        t[p].val=x;
        return ;
    }
    int m=mid;
    if(x<=m) modify(x,lch);
    else modify(x,rch);
    t[p].val=min(t[lch].val,t[rch].val);
}
void query(int l,int r,int p,int &num)
{
    if(t[p].l>=l&&t[p].r<=r)
    {
        num=min(num,t[p].val);
        return ;
    }
    int m=mid;
    if(l<=m) query(l,r,lch,num);
    if(r>m) query(l,r,rch,num);
}
int rec[MAXN],id[MAXN];
int main()
{
    int n,x,cas=1;
    char op[3];
    while(scanf("%d",&n)!=EOF&&n)
    {
        if(cas>1) printf("\n");
        printf("Case %d:\n",cas++);
        construct(1,MAXN,1);
        int up=0,max=0;
        memset(id,-1,sizeof(id));
        while(n--)
        {
            scanf("%s%d",op,&x);
            if(op[0]=='B'&&id[x]==-1)
            {
                rec[up]=x;
                id[x]=up;
                modify(x,1);
                up++;
                if(x>max) max=x;
            }
            else
            {
                int ans=-1,re=x;
                if(x<5000)
                {
                    for(int i=up-1;i>=0;i--)
                    {
                        if(rec[i]%x<re)
                        {
                            re=rec[i]%x;
                            ans=id[rec[i]];
                        }
                        if(re==0) break;
                    }
                }
                else
                {
                    int dd=MAXN/x;
                    int re=x;
                    for(int i=0;i<=dd;i++)
                    {
                        int num=INF;
                        int l=i*x;
                        if(l<1) l=1;
                        int r=(i+1)*x-1;
                        if(r>MAXN) r=MAXN;
                        query(l,r,1,num);
                        if(num==INF) continue;
                        if(num%x<re)
                        {
                            re=num%x;
                            ans=id[num];
                        }
                        else if(num%x==re)
                        {
                            if(id[num]>ans) ans=id[num];
                        }
                    }
                }
                if(ans!=-1) ans++;
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值