玲珑OJ 1129 - 喵哈哈村的战斗魔法师丶坏坏い月
2017-05-30 22:29
281 查看
1129 - 喵哈哈村的战斗魔法师丶坏坏い月
Time Limit:3s Memory Limit:256MByte
Submissions:315Solved:71
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
1 5 3 1 2 3 4 5 1 1 2 3 2 1 2 3 1 1 2 3
SAMPLE OUTPUT
-1 1
博客本来准备不更新了,今天看到这个题目 - -,想起如果用树维护又是树套树啥的,麻烦死了,结果看到题解->分块!
看了分块思想之后,感觉好巧妙啊,时间复杂度 O(m*sqrt(n)),这么难的数据结构题寥寥数十行就解决了,遂决定补题解!
官方题解:
H 喵哈哈村的战斗魔法师丶坏坏い月
常见的数据结构中,我们选择使用分块来处理这道题。
我们将n个数,分成sqrt(n)块,每块里面的元素最多有sqrt(n)个元素。对于每一个块,我们维护Upd[i]表示这个块整个增加了多少,Max[i]表示这个块内的最大值是多少。
对于查询和更新,如果完全囊括了块的话,我们就只对Upd[i]和Max[i]进行更新,否则的话,我们就暴力更新这个块的元素即可。
总体复杂度O(n*根号n)
Upd相当于一个标记,只起到记录的作用,两端暴力更新~
Time Limit:3s Memory Limit:256MByte
Submissions:315Solved:71
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
1 5 3 1 2 3 4 5 1 1 2 3 2 1 2 3 1 1 2 3
SAMPLE OUTPUT
-1 1
博客本来准备不更新了,今天看到这个题目 - -,想起如果用树维护又是树套树啥的,麻烦死了,结果看到题解->分块!
看了分块思想之后,感觉好巧妙啊,时间复杂度 O(m*sqrt(n)),这么难的数据结构题寥寥数十行就解决了,遂决定补题解!
官方题解:
H 喵哈哈村的战斗魔法师丶坏坏い月
常见的数据结构中,我们选择使用分块来处理这道题。
我们将n个数,分成sqrt(n)块,每块里面的元素最多有sqrt(n)个元素。对于每一个块,我们维护Upd[i]表示这个块整个增加了多少,Max[i]表示这个块内的最大值是多少。
对于查询和更新,如果完全囊括了块的话,我们就只对Upd[i]和Max[i]进行更新,否则的话,我们就暴力更新这个块的元素即可。
总体复杂度O(n*根号n)
Upd相当于一个标记,只起到记录的作用,两端暴力更新~
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long LL; const int N = 100000; int n,m; LL a ,Max ,Upd ; int pos ; int block = 0; void reset(int x) { int l=(x-1)*block+1,r=min(x*block,n); for(int i=l; i<=r; i++) Max[x]=max(Max[x],a[i]); } void update(int x,int y,LL v) { if(pos[x]==pos[y]) { for(int i=x; i<=y; i++)a[i]=a[i]+v; } else { for(int i=x; i<=pos[x]*block; i++)a[i]=a[i]+v; for(int i=(pos[y]-1)*block+1; i<=y; i++)a[i]=a[i]+v; } reset(pos[x]); reset(pos[y]); for(int i=pos[x]+1; i<pos[y]; i++) Upd[i]+=v; } int findidx(int x,LL v) { int l=(x-1)*block+1,r=min(x*block,n); for(int i=l; i<=r; i++) { if(a[i]+Upd[x]>=v) return i; } } int query(int x,int y,LL v) { if(pos[x]==pos[y]) { for(int i=x; i<=y; i++)if(a[i]+Upd[pos[i]]>=v) return i; } else { ///暴力找左边 for(int i=x; i<=pos[x]*block; i++) if(a[i]+Upd[pos[i]]>=v) return i; ///分块找中间 for(int i=pos[x]+1; i<pos[y]; i++) if(Max[i]+Upd[i]>=v) { return findidx(i,v); } ///暴力找右边 for(int i=(pos[y]-1)*block+1; i<=y; i++) if(a[i]+Upd[pos[i]]>=v) return i; } return -1; } int main() { int T; scanf("%d",&T); while(T--) { memset(Max,0,sizeof(Max)); memset(Upd,0,sizeof(Upd)); scanf("%d%d",&n,&m); block = int(sqrt(n)); for(int i=1; i<=n; i++) { scanf("%lld",&a[i]); pos[i]=(i-1)/block+1; ///记录每个元素属于哪个块 } int k; ///块的个数 if(n%block)k=n/block+1; else k=n/block; for(int i=1; i<=k; i++) { reset(i); } while(m--) { int opt,l,r; LL v; scanf("%d%d%d%lld",&opt,&l,&r,&v); if(opt==1) { printf("%d\n",query(l,r,v)); } else { update(l,r,v); } } } return 0; }
相关文章推荐
- ifrog 1129 喵哈哈村的战斗魔法师丶坏坏い月 线段树||分块
- LonLife-ACM 1129 - 喵哈哈村的战斗魔法师丶坏坏い月
- 玲珑学院1129 - 喵哈哈村的战斗魔法师丶坏坏い月(线段树)
- 玲珑学院OJ 1129 喵哈哈村的战斗魔法师丶坏坏い月【线段树查询最左端大于某个数的操作】
- 玲珑学院1129 - 喵哈哈村的战斗魔法师丶坏坏い月(分块)
- 1129 - 喵哈哈村的战斗魔法师丶坏坏い月(线段树)@
- 1129 - 喵哈哈村的战斗魔法师丶坏坏い月 线段树
- 玲珑杯1129-喵哈哈村的战斗魔法师丶坏坏い月
- 1129 - 喵哈哈村的战斗魔法师丶坏坏い月(河南专场)
- 玲珑学院OJ 1129 喵哈哈村的战斗魔法师丶坏坏い月【暴力分块】
- “玲珑杯”线上赛 Round #15 河南专场 H -- 喵哈哈村的战斗魔法师丶坏坏い月 分块/线段树
- 玲珑oj 1129
- QT学习8:准备战斗
- HR的战斗历史
- POJ-1129 Pie 解题报告
- PQ分区魔法师教程
- <cocos2d-x for wp7>使用cocos2d-x制作基于Tile地图的游戏:不一样的战斗(回合制战斗)(四)
- 战斗中的取消:《战神》与动作游戏设计
- mysql error 1129 错误
- 疯狂人生战斗精神总结