poj3145(线段树)

来源:互联网 发布:手机长时间摄像软件 编辑:程序博客网 时间:2024/06/05 05:43

题意:两种操作,一种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;}

0 0
原创粉丝点击