LonLife-ACM 1129
来源:互联网 发布:淘宝hd 微淘 编辑:程序博客网 时间:2024/05/29 15:05
原题链接
1129 - 喵哈哈村的战斗魔法师丶坏坏い月
Time Limit:3s Memory Limit:256MByte
Submissions:381Solved:85
DESCRIPTION
坏坏い月是月大叔的ID,他是一个掌握者772002种魔法的物理系战士,最擅长的技能就是搞事。今天他又要开始搞事了。
给你n个数,你需要实现一下操作:
l r v ,在[l,r]区间内找到第一个大于等于v的数,输出这个数的下标,如果找不到的话,请输出-1噢
l r v,让[l,r]区间所有数增加v
INPUT
输入第一行包含一个正整数t(1≤t≤100) ,表示有t组数据对于每组数据:第一行包含两个整数n(1≤n≤100000),q(1≤q≤100000),表示数的个数,以及询问的个数。第二行包含n个整数ai(1≤ai≤1000000000)接下来q行,每行四个整数opt(1≤opt≤2),l,r(1≤l≤r≤n),v(1≤v≤1000000000)
OUTPUT
对于每个询问,输出一行表示答案.
SAMPLE INPUT
15 31 2 3 4 51 1 2 32 1 2 31 1 2 3
SAMPLE OUTPUT
-11
常见的数据结构中,我们选择使用分块来处理这道题。
我们将n个数,分成sqrt(n)块,每块里面的元素最多有sqrt(n)个元素。对于每一个块,我们维护Upd[i]表示这个块整个增加了多少,Max[i]表示这个块内的最大值是多少。
对于查询和更新,如果完全囊括了块的话,我们就只对Upd[i]和Max[i]进行更新,否则的话,我们就暴力更新这个块的元素即可。
#include <bits/stdc++.h>#define maxn 100005using namespace std;typedef long long ll;ll d[maxn], add[1005], maxs[1005];int m;int get(int k) {if(k <= m * m)return k % m ? k / m + 1 : k / m;return m;}void update(int l, int r, ll p, int h) {for(int i = l; i <= r; i++) {d[i] += p;maxs[h] = max(maxs[h], d[i]+add[h]);}}int find(int l, int r, ll v, int h) {for(int i = l; i <= r; i++) {if(d[i] + add[h] >= v) return i;}return -1;}int main() {//freopen("in.txt", "r", stdin);int t;scanf("%d", &t);while(t--) {memset(add, 0, sizeof(add));memset(maxs, 0, sizeof(maxs));int q, n;scanf("%d%d", &n, &q); for(int i = 1; i <= n; i++) scanf("%lld", d+i);m = sqrt(n);for(int i = 1; i <= m; i++) {for(int j = (i-1)*m+1; j <= i*m; j++) {maxs[i] = max(maxs[i], d[j]);}}if(m * m < n) {for(int i = m * m + 1; i <= n; i++) {maxs[m] = max(maxs[m], d[i]);}}while(q--) {int t, l, r;ll v;scanf("%d%d%d%lld", &t, &l, &r, &v);int f1 = get(l);int f2 = get(r);if(t == 2) {if(f1 == f2) {update(l, r, v, f1);}else {update(l, f1*m, v, f1);update((f2-1)*m+1, r, v, f2);for(int i = f1+1; i < f2; i++) {add[i] += v;maxs[i] += v;}}}else {if(f1 == f2) {int k = find(l, r, v, f1);printf("%d\n", k);}else {int k = find(l, f1*m, v, f1);if(k != -1){ printf("%d\n", k); continue;}int sign = 0;for(int i = f1+1; i < f2; i++) {if(maxs[i] >= v) {sign = 1;printf("%d\n", find((i-1)*m+1, i*m, v, i));break;}}if(sign == 0) {printf("%d\n", find((f2-1)*m+1, r, v, f2));}}}}}return 0;}
阅读全文
0 0
- LonLife-ACM 1129
- Lonlife-ACM 1010 Alarm
- Lonlife-ACM Round #7
- Lonlife-ACM 1014 - Absolute Defeat [差分]
- Lonlife-ACM 1010 - Alarm(找规律+素数打表)
- Lonlife-ACM 1000 - Spoon Devil's 3-D Matrix(最小生成树)——“玲珑杯”acm比赛-试运行赛
- Lonlife-ACM 1005 - Spoon Devil's RP Test(同余定理)——“玲珑杯”acm比赛-试运行赛
- LonLife 1046 chess play
- LonLife 1051 My-graph
- LonLife 1052 See car
- Lonlife 1057 Private Value
- LonLife 1071 - Boring Game
- Lonlife 1016 Change of Life
- Lonlife 1056 A plus B
- lonlife oj 1029 - Bob and Alice are playing factors
- Lonlife 1000 - Spoon Devil's 3-D Matrix
- ACM
- acm
- Hello World!
- scrapy爬虫【1】→学习路上的坑和大家一起分享
- android 插件化学习
- 多线程-实现Runnable接口的方式卖电影票案例
- [方差+lucas定理] 51nod 算法马拉松25 D. 小Q的集合
- LonLife-ACM 1129
- 3Sum Closest
- Java并发编程实战--通过线程转储信息来分析死锁
- OC中UITableView创建及原理
- 在java中String a=""和String a=null的差别
- 递归2 用递归求和。1+2+3+4+....n.
- 一行代码实现Android软键盘与EditText的交互
- 递归3 递归函数求n的阶乘
- 编程练习(第十五周)