mthoutai

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题目地址:http://codeforces.com/contest/551/problem/E
将n平均分成sqrt(n)块,对每一块从小到大排序,并设置一个总体偏移量。
改动操作:l~r区间内,对两端的块进行暴力处理,对中间的总体的块用总体偏移量标记添加了多少。时间复杂度: O(2*sqrt(n)+n/sqrt(n)).
查询操作:对每一块二分。查找y-总体偏移量。找到最左边的和最右边的。时间复杂度:O(sqrt(n)*log(sqrt(n)))。
代码例如以下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
#include <time.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
//#pragma comment(linker, "/STACK:1024000000")
//const int mod=9901;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=500000+10;
LL b[MAXN];
struct node
{
        LL x;
        int id;
}fei[MAXN];
int BS1(int low, int high, LL x)
{
        int mid, ans=-1;
        while(low<=high){
                mid=low+high>>1;
                if(fei[mid].x<=x){
                        ans=mid;
                        low=mid+1;
                }
                else high=mid-1;
        }
        return ans;
}
int BS2(int low, int high, LL x)
{
        int mid, ans=-1;
        while(low<=high){
                mid=low+high>>1;
                if(fei[mid].x>=x){
                        ans=mid;
                        high=mid-1;
                }
                else low=mid+1;
        }
        return ans;
}
bool cmp(node x, node y)
{
        if(x.x==y.x) return x.id<y.id;
        return x.x<y.x;
}
int main()
{
        int n, q, i, j, l, r, k, min1, max1, z, ll, rr, tmp, tot;
        LL y, x;
        while(scanf("%d%d",&n,&q)!=EOF){
                for(i=0;i<n;i++){
                        scanf("%I64d",&fei[i].x);
                        fei[i].id=i;
                }
                k=sqrt(n*1.0);
                tot=(n+k-1)/k;
                for(i=0;i<tot;i++){
                        sort(fei+i*k,fei+min((i+1)*k,n),cmp);
                }
                memset(b,0,sizeof(b));
                while(q--){
                        scanf("%d",&z);
                        if(z==1){
                                scanf("%d%d%I64d",&l,&r,&x);
                                l--;r--;
                                ll=l/k;rr=r/k;
                                for(i=ll*k;i<(ll+1)*k&&i<n;i++){
                                        if(fei[i].id>=l&&fei[i].id<=r){
                                                fei[i].x+=x;
                                        }
                                }
                                sort(fei+ll*k,fei+min((ll+1)*k,n),cmp);
                                if(ll!=rr){
                                        for(i=rr*k;i<n&&i<(rr+1)*k;i++){
                                                if(fei[i].id>=l&&fei[i].id<=r){
                                                        fei[i].x+=x;
                                                }
                                        }
                                        sort(fei+rr*k,fei+min((rr+1)*k,n),cmp);
                                }
                                for(i=ll+1;i<rr;i++){
                                        b[i]+=x;
                                }
                        }
                        else{
                                scanf("%I64d",&y);
                                min1=max1=-1;
                                for(i=0;i<tot;i++){
                                        tmp=BS2(i*k,min((i+1)*k-1,n-1),y-b[i]);
                                        if(tmp!=-1&&fei[tmp].x==y-b[i]){
                                                min1=fei[tmp].id;
                                                break;
                                        }
                                }
                                for(i=tot-1;i>=0;i--){
                                        tmp=BS1(i*k,min((i+1)*k-1,n-1),y-b[i]);
                                        if(tmp!=-1&&fei[tmp].x==y-b[i]){
                                                max1=fei[tmp].id;
                                                break;
                                        }
                                }
                                if(min1==-1&&max1==-1){
                                        puts("-1");
                                }
                                else printf("%d\n",max1-min1);
                        }
                }
        }
        return 0;
}
posted on 2017-07-28 15:15  mthoutai  阅读(278)  评论(0编辑  收藏  举报