hdu 3303 Harmony Forever (线段树 + 抽屉原理)
http://acm.hdu.edu.cn/showproblem.php?pid=3303
Harmony Forever
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 813 Accepted Submission(s): 222
Fortunately, the method of unlocking the key to true Harmony is just discovered by a group of philosophers. It is recorded on a strange meteorite which has just hit the earth. You need to decipher the true meaning behind those seemingly random symbols ... More precisely, you are to write a program which will support the following two kinds of operation on an initially empty set S :
1. B X : Add number X to set S . The Kth command in the form of B X always happens at time K , and number X does not belong to set S before this operation. 2. A Y : Of all the numbers in set S currently, find the one which has the minimum remainder when divided by Y . In case a tie occurs, you should choose the one which appeared latest in the input. Report the time when this element is inserted.
It is said that if the answer can be given in the minimum possible time, true Harmony can be achieved by human races. You task is to write a program to help us.
T = 0 indicates the end of input file and should not be processed by your program.
题解:
很显然的线段树问题,但是这个题有点技巧就是利用抽屉原理来降低复杂度。
什么是抽屉原理?抽屉原理也叫鸽巢原理,鸽巢原理就是给定N+1个数,则必定至少有两个数Mod(N)的余数是相同的! 假设要求的MOD是Y,则首先查找[0,Y-1]区间的最小值,因为这样的区间不会有两个数的余数相同,记录下结果。然后依次查找[Y,Y+Y-1],[Y+Y,Y+Y+Y-1]。。。。等区间,每个区间都会找出一个最小值,将这些最小值对Y进行取模,得到最小值!
这题还要注意:范围较小的时候直接查找,否则TLE。
代码:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector> using namespace std;
#define N 500000
#define INF 100000000
vector<int> vct; struct Nod
{
int l,r,mins;
}node[(N<<)+]; int maxInput;
int posArray[N+]; void building(int l,int r,int p)
{
node[p].l = l;
node[p].r = r;
node[p].mins = INF;
if(l==r) return ;
int mid = (l+r)>>;
building(l,mid,p<<);
building(mid+,r,p<<|);
} void update(int x,int p)
{
if(node[p].l>x||node[p].r<x) return;
if(node[p].l == node[p].r&&node[p].l==x)
{
node[p].mins = x;
return;
}
update(x,p<<);
update(x,p<<|);
node[p].mins = min(node[p<<].mins,node[p<<|].mins);
}
/**RE的查询方式 int query(int l,int r,int p) //找[l,r]区间的最小值
{
if(node[p].l == l && node[p].r == r) return node[p].mins;
int mid = (node[p].l+node[p].r)>>1;
if(r<=mid) return query(l,r,p<<1);
else if(mid>l) return query(l,r,p<<1|1);
else return min(query(l,mid,p<<1),query(mid+1,r,p<<1|1));
} */
int Query(int l,int r,int index)//找[l,r]区间的最小值
{
if(node[index].l>r || node[index].r<l) return INF;
if(node[index].l>=l && node[index].r<=r) return node[index].mins;
if(node[index].l < node[index].r)
return min(Query(l,r,index<<),Query(l,r,index<<|));
return INF;
} int search(int y)
{
int minAns = INF,id = ,i;
for(i=vct.size()-;i>=;i--)
{
if(vct[i]%y== ) return i+;
if(vct[i]%y<minAns)
{
minAns = vct[i]%y;
id = i+;
}
}
return id;
} int solve(int y) //抽屉原理
{
int l=,r=y-,minAns=INF,id,temp;
while(l<=maxInput)
{
if(maxInput<r) r=N;
temp = Query(l,r,);
if(temp!=INF)
{
if(temp%y<minAns)
{
minAns = temp%y;
id = posArray[temp];
}
else if(temp%y == minAns && posArray[temp] > id)
{
id = posArray[temp];
}
}
l+=y;
r+=y;
}
return id;
} int main()
{
int t,cas=;
while(~scanf("%d",&t)&&t)
{
building(,N,);
char op[];
maxInput = ;
vct.clear();
if(cas!=) printf("\n");
printf("Case %d:\n",cas++);
while(t--)
{
scanf("%s",op);
if(op[]=='B')
{
int x;
scanf("%d",&x);
if(maxInput<x) maxInput = x;
vct.push_back(x);
posArray[x] = vct.size();
update(x,);
}
else if(op[]=='A')
{
int y;
scanf("%d",&y);
if(vct.size()==) puts("-1");
else if(y<=) printf("%d\n",search(y)); //防超时
else printf("%d\n",solve(y));
}
}
}
return ;
}
hdu 3303 Harmony Forever (线段树 + 抽屉原理)的更多相关文章
- HDU 3303 Harmony Forever 前缀和+树状数组||线段树
Problem Description We believe that every inhabitant of this universe eventually will find a way to ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- 浅谈可持久化Trie与线段树的原理以及实现(带图)
浅谈可持久化Trie与线段树的原理以及实现 引言 当我们需要保存一个数据结构不同时间的每个版本,最朴素的方法就是每个时间都创建一个独立的数据结构,单独储存. 但是这种方法不仅每次复制新的数据结构需要时 ...
- HDU 5091---Beam Cannon(线段树+扫描线)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) Total Sub ...
- HDU 5820 (可持久化线段树)
Problem Lights (HDU 5820) 题目大意 在一个大小为50000*50000的矩形中,有n个路灯.(n<=500000) 询问是否每一对路灯之间存在一条道路,使得长度为|x1 ...
- HDU 5861 Road (线段树)
Road 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Description There are n villages alo ...
随机推荐
- Android 自学之进度条ProgressBar
进度条(ProgressBar)也是UI界面中的一种非常使用的组件,通常用于向用户显示某个耗时完成的百分比.因此进度条可以动态的显示进度,因此避免长时间地执行某个耗时操作时,让用户感觉程序失去了响应, ...
- [转]windows下安装Object-C开发环境
本文转自:http://hi.baidu.com/jeremylai/item/f40b9116cb3c5d582b3e22f5 在Windows下搭建Objective C开发环境,需要到GNUst ...
- 为Debain &&Centos安装dig
Debain&Ubuntu sudo apt-get install dnsutils Fdeoar&Centos yum install bind-utils
- dede常用命令
获取日期:全局:{dede:field.pubdate function="MyDate('Y-m-d H:i',@me)"/} 局部:[field:pubdate funct ...
- 几种RAID技术比较
http://book.51cto.com/art/201310/412862.htm RAID(廉价磁盘冗余阵列)技术主要是为了改善磁盘的访问延迟,增强磁盘的可用性和容错能力.目前服务器级别的计算机 ...
- Activiti初学者教程
http://wenku.baidu.com/view/bb7364ad4693daef5ff73d32.html 1. 初识Activiti 1.1. 工作流与工作流引擎 工作流(workflow) ...
- rs.open sql,conn,3,1中3,1代表什么
RecordSet中的open完全的语法是 SecordSet.Open Source,ActiveConnection,CursorType,LockType,Options 例如: rs.open ...
- ASP缓存类收集
木鸟写的 '********************************************** ' vbs Cache类 ' ' 属性valid,是否可用,取值前判断 ' 属性name,ca ...
- 鼠标点击input时,placeholder中的提示信息消失
html代码: <input type="text" placeholder="多个关键词空格隔开"> 鼠标点击input时,placeholder ...
- strcpy(),string使用问题
两个CString,把一个赋值给另外一个,用strncpy出现问题,直接=赋值正确了,不知道为什么?