题目链接:http://codeforces.com/problemset/problem/551/E

题意:给定一个长度为N的序列。 有2个操作 1 l r v:序列第l项到第r项加v(区间加),  2 v:求整个序列中值为v的数的位置的差值最大是多少。不存在输出-1.

思路:分块。 每块维护该块序列排序后的序列。 对于区间修改,我们定义一个lazy标记。对于整块的修改我们只修改lazy, 其他情况暴力修改。然后情况该块后重新加入修改后的块然后排序。 对于查询操作。查询每块时v应该减去该块的lazy值。 然后2分查即可。

#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<iostream>
#include<map>
using namespace std;
typedef long long int LL;
const int MAXN = * + ;
int belong[MAXN], block, num, L[MAXN], R[MAXN];
int n, q;
LL val[MAXN], lazy[MAXN];
struct Node{
LL v;
int id;
Node(LL _v, int _id) :v(_v), id(_id){};
bool operator < (const Node &a)const{
return v==a.v?id<a.id:v<a.v;
}
};
vector<Node>Bval[MAXN];
void build(){
block = (int)sqrt(n+0.5);
num = n / block; if (n%block){ num++; }
for (int i = ; i <= num; i++){
lazy[i] = ; Bval[i].clear();
L[i] = (i - )*block + ; R[i] = i*block;
}
R[num] = n;
for (int i = ; i <= n; i++){
belong[i] = ((i - ) / block) + ;
}
for (int i = ; i <= num; i++){
for (int k = L[i]; k <= R[i]; k++){
Bval[i].push_back(Node(val[k],k));
}
sort(Bval[i].begin(), Bval[i].end());
}
}
void modify(int st,int ed, LL v){
if (belong[st] == belong[ed]){
for (int i = st; i <= ed; i++){
val[i] += v;
}
Bval[belong[st]].clear();
for (int i = L[belong[st]]; i <= R[belong[st]]; i++){
Bval[belong[st]].push_back(Node(val[i], i));
}
sort(Bval[belong[st]].begin(), Bval[belong[st]].end());
return;
}
for (int i = st; i <= R[belong[st]]; i++){
val[i] += v;
}
Bval[belong[st]].clear();
for (int i = L[belong[st]]; i <= R[belong[st]]; i++){
Bval[belong[st]].push_back(Node(val[i], i));
}
sort(Bval[belong[st]].begin(), Bval[belong[st]].end());
for (int i = belong[st] + ; i < belong[ed]; i++){
lazy[i] += v;
}
for (int i = L[belong[ed]]; i <= ed; i++){
val[i] += v;
}
Bval[belong[ed]].clear();
for (int i = L[belong[ed]]; i <= R[belong[ed]]; i++){
Bval[belong[ed]].push_back(Node(val[i], i));
}
sort(Bval[belong[ed]].begin(), Bval[belong[ed]].end());
}
int query(LL v){
int L = -, R = -;
for (int i = ; i <= num; i++){
LL _v = v-lazy[i];
int pos = lower_bound(Bval[i].begin(), Bval[i].end(), Node(_v,)) - Bval[i].begin();
if (pos >= && pos < Bval[i].size() && Bval[i][pos].v == _v){
L = Bval[i][pos].id; break;
}
}
if (L == -){ return -; }
for (int i = num; i > ; i--){
LL _v = v - lazy[i];
int pos = (lower_bound(Bval[i].begin(), Bval[i].end(), Node( _v + ,)) - Bval[i].begin())-;
if (pos >= && pos < Bval[i].size() && Bval[i][pos].v == _v){
R = Bval[i][pos].id; break;
}
}
return R - L;
}
int main(){
//#ifdef kirito
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
//#endif
// int start = clock();
while (~scanf("%d%d", &n,&q)){
for (int i = ; i <= n; i++){
scanf("%lld", &val[i]);
}
build();
for (int i = ; i <= q; i++){
int type, l, r, v;
scanf("%d", &type);
if (type == ){
scanf("%d%d%lld", &l, &r, &v);
modify(l, r, v);
}
else{
scanf("%lld", &v);
printf("%d\n", query(v));
}
}
}
//#ifdef LOCAL_TIME
// cout << "[Finished in " << clock() - start << " ms]" << endl;
//#endif
return ;
}

CodeForces 551E 分块的更多相关文章

  1. Codeforces 551E GukiZ and GukiZiana(分块思想)

    题目链接 GukiZ and GukiZiana 题目大意:一个数列,支持两个操作.一种是对区间$[l, r]$中的数全部加上$k$,另一种是查询数列中值为$x$的下标的最大值减最小值. $n < ...

  2. (分块)GukiZ and GukiZiana CodeForces - 551E

    题意: 给你一段序列,并且有两种操作 操作①:将序列中从l-r每个元素加上x 操作②:在序列中找到ai=aj=y,j-i的最大值,如果找不到则输出-1 思路: 直接分块暴力即可 对于区间加,普通标记加 ...

  3. Codeforces 551E - GukiZ and GukiZiana(分块)

    Problem E. GukiZ and GukiZiana Solution: 先分成N=sqrt(n)块,然后对这N块进行排序. 利用二分查找确定最前面和最后面的位置. #include < ...

  4. CodeForces 551E GukiZ and GukiZiana

    GukiZ and GukiZiana Time Limit: 10000ms Memory Limit: 262144KB This problem will be judged on CodeFo ...

  5. CodeForces 444C 分块

    题目链接:http://codeforces.com/problemset/problem/444/C 题意:给定一个长度为n的序列a[].起初a[i]=i,然后还有一个色度的序列b[],起初b[i] ...

  6. CodeForces 455D 分块

    题目链接:http://codeforces.com/problemset/problem/455/D 题意:给定一个长度为n的序列a[]. m次操作.共有两种操作 1 l r:将序列的a[l].a[ ...

  7. CodeForces 103D 分块处理

    题目链接:http://codeforces.com/problemset/problem/103/D 题意:给定一个长度为n的序列.然后q个询问.每个询问为(a,b),表示从序列第a项开始每b项的加 ...

  8. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 828E) - 分块

    Everyone knows that DNA strands consist of nucleotides. There are four types of nucleotides: "A ...

  9. CodeForces 13E 分块

    题目链接:http://codeforces.com/problemset/problem/13/E 题意:给定n个弹簧和每个弹簧初始的弹力a[].当球落在第i个位置.则球会被弹到i+a[i]的位置. ...

随机推荐

  1. Codeforces Round #342 (Div. 2) D. Finals in arithmetic(想法题/构造题)

    传送门 Description Vitya is studying in the third grade. During the last math lesson all the pupils wro ...

  2. <<< Oracle表空间创建、修改、删除基本操作

    ORACLE 中,表空间是数据管理的基本方法,所有用户的对象要存放在表空间中,也就是用户有空间的使用权,才能创建用户对象 create tablespace myts  //建立表空间,名为mytsd ...

  3. SDL鼠标事件

    鼠标事件有这么多种,手柄的可以忽视,Sdl.SDL_KEYDOWN,Sdl.SDL_KEYUP,Sdl.SDL_MOUSEMOTION,Sdl.SDL_MOUSEBUTTONDOWN,Sdl.SDL_ ...

  4. 深入理解javascript原型和闭包(16)——完结

    之前一共用15篇文章,把javascript的原型和闭包. 首先,javascript本来就“不容易学”.不是说它有多难,而是学习它的人,往往都是在学会了其他语言之后,又学javascript.有其他 ...

  5. nginx图片处理

    前言 不管一个系统或网站的大与小,都存在相应的图片处理,生成缩略图.为图片加水印等等,如果涉及到APP端,这个图片的处理需求变得更加重要了,因为在目前看来,客户端的屏幕大小不一,会导致以下问题: 1. ...

  6. JDI tutorial (trace example)

    Components Debugger Interfaces / |--------------| / | VM | debuggee ----( |--------------| <----- ...

  7. tyvj1004 滑雪

    描述     trs喜欢滑雪.他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形.为了得到更快的速度,滑行的路线必须向下倾斜.    例如样例中的那个矩形,可以从某 ...

  8. .htaccess 基础教程(四)Apache RewriteCond 规则参数

    Apache模块 mod_rewrite 提供了一个基于正则表达式分析器的重写引擎来实时重写URL请求.它支持每个完整规则可以拥有不限数量的子规则以及附加条件规则的灵活而且强大的URL操作机制.此UR ...

  9. C++基础知识(3)---new 和 delete

    学过c语言的人都知道,c语言中动态分配内存空间使用的是库函数malloc,calloc,realloc以及free.而c++中所使用的是关键字new和delete.如 动态分配 new  ,  撤销内 ...

  10. dynamic和var的区别

    1.var声明一个局部变量只是一种简化语法,它要求编译器根据一个表达式推断具体的数据类型. 2.var只能用于声明方法内部的局部变量,而dynamic可用于局部变量,字段,参数. 3.表达式不能转型为 ...