hdu3303
分析:一个最暴力的想法是把加入到集合S的数据一个个按顺序保存起来,然后每次查询的时候由后向前计算余数,如果遇到余数为0的,就直接把时间输出,否则就一直比较到最后找余数最小时间最晚的,这样查询的时间复杂度是n(当前S的元素个数)。
另一个想法就是利用x、y的数据范围,建线段树表示[1,500000]这个区间,用来更新和查询任意[a,b]区间的最小值。因为[m*y,(m + 1)y - 1]内每个数除y的余数都是唯一的,而且被除数越小余数就越小,所以我们可以查询每个小区间的最小值,再比较应该取哪个时间就可以了。查询的时间复杂度为(maxN/y)*lg(maxN),可见y越大查询时间越短。但y很小时,就要进行很多次对线段树的查询才能得出结果,所以当y很小时,应该用暴力的方法查询。
#pragma warning(disable:4996)
#include <cstdio>
#include <set>
#include <stack>
#include <vector>
#include <algorithm>
#include <map>
#define maxN 1000001
using namespace std;
int sum[maxN << ], data[maxN];
int stk[maxN], s;
//向上更新,rt是要更新的节点的下标
void pushUp(int rt){
int m = rt << ;
if (sum[m] != -){
sum[rt] = sum[m];
}
else{
sum[rt] = sum[m | ];
}
}
//初始化线段树
void initTree(int a, int b, int rt){
sum[rt] = -;
if (a == b){
return;
}
int m = rt << ;
initTree(a, (a + b) / , m);
initTree((a + b) / + , b, m | );
}
//更新节点
void update(int tgt, int time, int a, int b, int rt){
if (a == b){
sum[rt] = a;
data[a] = time;
return;
}
int m = rt << ;
if (tgt > (a + b) / ){//更新右子树
update(tgt, time, (a + b) / + , b, m | );
}
else{//更新左子树
update(tgt, time, a, (a + b) / , m);
}
pushUp(rt);
}
int query(int ta, int tb, int a, int b, int rt){
if (ta <= a && tb >= b || sum[rt] == -){
return sum[rt];
}
int ret = -, m = rt << ;
if (ta <= (a + b) / ){//查询左子树
ret = query(ta, tb, a, (a + b) / , m);
}
if (ret == - && tb > (a + b) / ){//查询右子树
ret = query(ta, tb, (a + b) / + , b, m | );
}
return ret;
}
int query(int x){
int ret = 0xfffffff, start = , end = x - ,rmdRet = x;
do{
int temp = query(start, end, , , );
int rmdTemp = temp % x;
if (temp != -){
if(rmdRet > rmdTemp){
rmdRet = rmdTemp;
ret = temp;
}
else if (rmdRet == rmdTemp && data[ret] < data[temp]){
ret = temp;
}
}
start = end + ;
end += x;
}while (end < );
if (ret == 0xfffffff){
return -;
}
else{
return data[ret];
}
}
int main(){
int t, x, time;
char op;
int caseNum = ;
while (scanf("%d", &t), t){
if (caseNum != ){
printf("\n");
}
printf("Case %d:\n", caseNum++);
initTree(, , );
s = ;
time = ;
for (int i = ; i <= t; i++){
scanf("%*c%c%d", &op, &x);
if (op == 'B'){
update(x, time++, , , );
stk[s++] = x;
}
else{
if (x > ){
printf("%d\n", query(x));
}
else{
int rmd = x,ans = -;
bool flag = false;
for (int i = s - ; i >= ; i--){
if (stk[i] % x == ){
printf("%d\n", i + );
flag = true;
break;
}
else if(stk[i] % x < rmd){
rmd = stk[i] % x;
ans = i + ;
}
}
if (!flag){
printf("%d\n", ans);
}
}
}
}
}
return ;
}
hdu3303的更多相关文章
- JS里关于事件的常被考察的知识点:事件流、事件广播、原生JS实现事件代理
1.JS里面的事件流 DOM2级事件模型中规定了事件流的三个阶段:捕获阶段.目标阶段.冒泡阶段,低版本IE(IE8及以下版本)不支持捕获阶段 捕获事件流:Netscape提出的事件流,即事件由页面元素 ...
随机推荐
- 关于Webpack的的认识及傻瓜式教学
刚学习了Webpack,ememememememememem就赶脚是一个打包工具,将js.css.json.img等等通通打包为最终的文件,最后渲染为一个页面. 也是终于捋清了Webpack的思路,在 ...
- Js 使用小技巧总结(1)
1.Js 的时间控制,小于初始时间,大于截止时间 <script type="text/javascript"> window.onload = Game ...
- ASP.NET MVC5 之 客户端实现文件的下载
MVC 实现下载功能主要借助于 File 属性: //下载文件接口 public ActionResult GetTrackTempIsc(ICSModels icsModels) { bool fl ...
- Linux环境下修改MySQL数据库对表名大小写不敏感
Linux系统中MySQL对数据库名称和表名是大小写敏感的,这就导致了一些麻烦,虽然已经建立了表和数据,但因为大小写导致无法找到表. MySQL数据库对表名大小写不敏感的设置方法如下: 1.查看MyS ...
- [转]Mysql之Union用法
转自:http://blog.csdn.net/ganpengjin1/article/details/9090405 MYSQL中的UNION UNION在进行表链接后会筛选掉重复的记录,所以在表链 ...
- 【转载】Hadoop分布式文件系统HDFS的工作原理详述
转载请注明来自36大数据(36dsj.com):36大数据 » Hadoop分布式文件系统HDFS的工作原理详述 转注:读了这篇文章以后,觉得内容比较易懂,所以分享过来支持一下. Hadoop分布式文 ...
- const学习(续)
续接上一篇<C++ const学习> const与成员函数 之前说到了const修饰成员函数本身. const成员函数不能修改对象成员值 对于const或者费const对象都可以调用con ...
- C++学习笔记(一)之指针
指向指针的引用 ; int * p; int *&r = p; //r为对指针p的引用 r = &i; //r为对p的引用,故对r赋值即将p指向i *r = ; //更新i的值 通过* ...
- Java 基础入门随笔(7) JavaSE版——面向对象定义、特征:封装、构造函数
面向对象 面向过程:对于面向过程思想,强调的是过程(动作). 面向对象:对于面向对象思想,强调的是对象(实体). 特点: 1,面向对象就是一种常见的思想.符合人们的思考习惯.2,面向对象的出现,将复杂 ...
- 判断excel是否包含隐藏sheet
Workbook workbook =new XSSFWorkbook("D:\\文档1.xlsx"); System.out.println(workbook.isSheetHi ...