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
- poj3145(线段树)
- POJ3145: Harmony Forever
- 线段树?线段树!
- 线段树?线段树!
- poj3145 / hdu3303 Harmony Forever(树状数组 + 鸽巢原理)
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- shell编程笔记——反引号(``)
- MFC网速及流量监控程序的实现(一)
- 【C++学习笔记】01_C++概述
- 从想法到实现的关键五步
- 函数ceil 容易忽略的问题
- poj3145(线段树)
- parameterMap与parameterClass
- Raphael.js API 之 Element.attr()
- java中常见的异常类
- ldap 身份验证的通用步骤
- 堆组织表、索引组织表、索引聚簇表
- java泛型
- ubuntu 下的 dnw 下载安装和使用
- 【从源码看Android】03Android MessageQueue消息循环处理机制(epoll实现)