码迷,mamicode.com
首页 > 其他好文 > 详细

poj3145(线段树)

时间:2014-06-21 22:38:16      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:des   style   class   blog   code   com   

题意:两种操作,一种B t向集合中插入元素t,另一种A t,查询集合中模y最小的数,如果有多个最小则取最后插入的那个。操作数<=40000,1 ≤ t≤ 500 000,1 ≤ y ≤ 1 000 000.


解法:每个数都插入等于其坐标的位置。线段树维护区间最小值,然后每次询问都查询[0,y-1],[y-1,2*y-1]....各循环节区间的最小值然后分别松弛答案。当y过小的时候,复杂度会退化,可以完全暴力枚举,这个复杂度和数据有关系。


代码:

/******************************************************
* @author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std;

#define eps 1e-8
#define zero(_) (abs(_)<=eps)
const double pi=acos(-1.0);
typedef unsigned long long LL;
const int Max=500110;
const int INF=1e9+7;
int tool[Max*10];
struct point
{
    int value;
    int time;
};
bool operator<(const point& a,const point& b)
{
    if(a.value!=b.value)
        return a.value<b.value;
    return a.time>b.time;
}
struct node
{
    int l,r;
    node *pl,*pr;
    point thing;
} nodes[2*Max];
int tot=0;
void buildtree(node *p,int left,int right)
{
    p->l=left;
    p->r=right;
    p->thing.value=INF;
    if(left==right)
    {
        return ;
    }
    int middle=(left+right)/2;
    tot++;
    p->pl=nodes+tot;
    buildtree(p->pl,left,middle);

    tot++;
    p->pr=nodes+tot;
    buildtree(p->pr,middle+1,right);
}
point query(node* p,int left,int right)
{
    if(p->l==left&&p->r==right)
        return p->thing;
    int middle=(p->l+p->r)/2;
    if(right<=middle)
        return query(p->pl,left,right);
    if(left>middle)
        return query(p->pr,left,right);
    return min(query(p->pl,left,middle),query(p->pr,middle+1,right));
}
void update(node* p,int pos,int time)
{
    // cout<<p->l<<" "<<p->r<<" "<<pos<<endl;
    if(p->l==pos&&p->r==pos)
    {
        p->thing.value=pos;
        p->thing.time=time;
        return ;
    }
    int middle=(p->l+p->r)/2;
    if(pos>middle)
        update(p->pr,pos,time);
    else
        update(p->pl,pos,time);
    p->thing=min(p->pl->thing,p->pr->thing);
}
int n;
int ma=0;
int time=1;
void solve(int t)
{
   if(t<=20000)
    {
        int ans=t;
        int out=0;
       for(int i=time-1;i>=1;i--)
       {
          // cout<<"           "<<time<<endl;
         if(tool[i]%t<ans)
         {
             ans=tool[i]%t;
             out=i;//cout<<"            "<<time<<" "<<i<<endl;
         }
            if(ans==0)
            break;
       }
        if(ans==t)
            puts("-1");
        else
            printf("%d\n",out);
        return;
    }
    point p;
    p.time=INF;
    p.value=t;
    point tool;
    for(int i=0; i<ma/t; i++)
    {
        tool=query(nodes,t*i,t*i+t-1);
        if(tool.value>=INF)
            continue;
        tool.value%=t;
        p=min(p,tool);
    }
    tool=query(nodes,t*(ma/t),t*(ma/t)+ma%t);
    if(tool.value<INF)
    {
        tool.value%=t;
        p=min(p,tool);
    }
    if(p.value==t)
        puts("-1");
    else
        printf("%d\n",p.time);
}
int main()
{
    int kk=1;
    while(scanf("%d",&n)==1&&n)
    {
        time=1;
        ma=0;
        printf("Case %d:\n",kk++);
        tot=0;
        buildtree(nodes,0,Max-10);
        while(n--)
        {
            char c;int t;
            getchar();
            scanf("%c%d",&c,&t);
            if(c=='B')
            {
                update(nodes,t,time);
                tool[time++]=t;
                ma=max(ma,t);
            }
            else
                solve(t);
        }
        printf("\n");
    }
    return 0;
}

poj3145(线段树),布布扣,bubuko.com

poj3145(线段树)

标签:des   style   class   blog   code   com   

原文地址:http://blog.csdn.net/xiefubao/article/details/32106861

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!