POJ 3145 线段树
来源:互联网 发布:怎么注册国外域名 编辑:程序博客网 时间:2024/06/10 07:30
题意:
一个初始为空的序列,两种操作:
1)A x:将x加入序列尾
2)B x :查询序列中的一个数A[i], 使 A[i] mod p最小的情况下, i最大, 输出i
思路:
用线段树维护数值区间内的最小的数是多少。
1)对于较小的p可以直接暴力,由于数据较水可过。不过其实可以离线处理询问,对于较小的p每加一个数就更新其答案,p相同的询问就可以一起算了(然而懒得写)。
2)对于较大的p,在区间[0, p - 1], [p, p * 2 - 1] ......内查询最小值即可。由于本题的特性可在线段树的查询时进行一些优化(见代码)。
调了好久,后来发现划分区间查询时的一个细节写错了。。。。。。后来又发现输出写错了。。。。。。
代码:
#include <cstdio>#include <iostream>#include <algorithm>#include <cmath>#include <cstring>#define Set(i,j) memset(i, j, sizeof(i))#define For(i,j,k) for(int i = j;i <= k;i++)#define Forr(i,j,k) for(int i = j;i >= k;i--)#define lc (h << 1)#define rc (h << 1 | 1)#define M ((L + R) >> 1)using namespace std;const int N = 500020, E = 40010;int n, cnt, A[E], now[N];struct Segment_Tree{int Min[N<<2];void init(){Set(Min, 0x3f), Set(now, 0);}void update(int h, int L, int R, int pos){Min[h] = min(Min[h], pos);if(L == R) return;if(pos <= M) update(lc, L, M, pos);else update(rc, M+1, R, pos);}int query(int h, int L, int R, int l, int r){if(Min[h] > 1e8 || (l <= L && r >= R)) return Min[h];int ret = 2e9;if(l <= M) ret = query(lc, L, M, l, r); if(ret <= N) return ret;if(r > M) ret = query(rc, M+1, R, l, r);return ret;}}Tree;int Read(){char c = getchar();for(;c > '9' || c < '0';c = getchar());int x = c - '0';for(c = getchar();c >= '0' && c <= '9';c = getchar()) x = x * 10 + c - '0';return x;}void Solve1(int p){int Ans = -1, Min = 2e9;Forr(i,cnt,1){if(A[i] % p < Min) Min = A[i] % p, Ans = i;if(!Min) break;}printf("%d\n", Ans);}void Solve2(int p){int Ans = 1e9, pos = 1e9;For(i,0,N/p){int t = Tree.query(1, 0, N, i * p, min(N, (i + 1) * p - 1));if(t <= N && t - i * p < Ans) Ans = t - i * p, pos = now[t];else if(t <= N && t - i * p == Ans) pos = max(pos, now[t]);}printf("%d\n", pos);}int main(){int CASE = 0;while(scanf("%d", &n) && n){if(CASE) puts("");printf("Case %d:\n", ++CASE);Tree.init();cnt = 0;while(n--){char Q[5];scanf("%s", Q);int x = Read();if(Q[0] == 'B'){Tree.update(1, 0, N, x);A[++cnt] = x;now[x] = cnt;}else{if(!cnt){puts("-1");continue;}if(x <= 3000) Solve1(x);else Solve2(x);}}}return 0;}
1 0
- POJ 3145 线段树
- poj 3145 Harmony Forever(线段树)
- POJ-3145-Harmony Forever-线段树暴力
- POJ 3145 线段树 分块?+暴力
- POJ 2777 线段树
- poj 3468 线段树
- 线段树 POJ 2352
- POJ 3264 线段树
- POJ 3468 线段树
- poj 2352 线段树
- poj 3225(线段树)
- poj 3225(线段树)
- poj 2528 线段树
- poj 2181 (线段树)
- POJ 2828 (线段树)
- POJ 2777 (线段树)
- POJ 2352 线段树
- POJ-4047-线段树
- 循环动画
- 再看社交网络
- mac os x 将C文件编译成.so库
- xml日期2016-01-07T11:33:58.000+08:00和正常日期互转
- iOS程序中的内存分配 栈区堆区全局区
- POJ 3145 线段树
- 深入理解JavaScript系列(4):立即调用的函数表达式
- 修改MySql密码
- Android API翻译之WebViewClient
- 用wamp5模拟一次AJAX请求
- leetcode 357 c++. Count Numbers with Unique Digits
- cf451e Devu and Flowers(容斥原理)
- mnesia锁数据时机
- java 语言中try catch的用处