codeforces 551E. GukiZ and GukiZiana 分块

题目链接

给出n个数, m个操作, 每个操作有两种, 将一段区间加上某个值, 或者询问一个k, a[i] = a[j] = k, 输出满足条件的最大的j-i, 如果没有输出-1。

做法是将数组分块, 第一次做这种, 抄的codeforces上面的代码...

#include<bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
multiset <int> s[1000];
const int maxn = 5e5+5;
int a[maxn], N, add[1005], n;
void modify(int l, int r, int val) {
    for(int i = l; i<=r; i++) {
        if(i%N==0&&i+N-1<=r) {
            add[i/N] += val;
            if(add[i/N]>1e9)
                add[i/N] = 1e9+1;
            i+=N-1;
        } else {
            s[i/N].erase(s[i/N].find(a[i]));
            a[i]+=val;
            if(a[i]>1e9)
                a[i] = 1e9+1;
            s[i/N].insert(a[i]);
        }
    }
}
int query(int x) {
    int l = -1, r = -2;
    for(int i = 0; i<n; i++) {
        if(a[i] + add[i/N] == x) {
            l = i;
            break;
        }
        if(i%N==0&&i+N-1<n) {
            if(s[i/N].find(x-add[i/N])==s[i/N].end())
                i+=N-1;
        }
    }
    for(int i = n-1; i>=0; i--) {
        if(a[i] + add[i/N] == x) {
            r = i;
            break;
        }
        if((1+i)%N == 0) {
            if(s[i/N].find(x-add[i/N]) == s[i/N].end())
                i = i-N+1;
        }
    }
    return r-l;
}
int main()
{
    int m, cnt = 0;
    cin>>n>>m;
    N = sqrt(n*1.0);
    for(int i = 0; i<n; i++) {
        scanf("%d", &a[i]);
        if(i&&i%N==0)
            cnt++;
        s[cnt].insert(a[i]);
    }
    while(m--) {
        int sign, l, r, val;
        scanf("%d", &sign);
        if(sign == 1) {
            scanf("%d%d%d", &l, &r, &val);
            l--, r--;
            modify(l, r, val);
        } else {
            scanf("%d", &val);
            cout<<query(val)<<endl;
        }
    }
    return 0;
}

 3.10 update 重新写了一发。

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<ll, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1e18;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 5e5+5;
vector<pll> b[800];
ll a[maxn], c[maxn], l[800], r[800], add[800], belong[maxn];
int n, cnt, block;
int ansx, ansy;
void rebuild(int x) {
    b[x].clear();
    for(int i = l[x]; i<=r[x]; i++) {
        b[x].pb(mk(a[i], i));
    }
    sort(b[x].begin(), b[x].end());
}
void update(int x, int y, int val) {
    if(belong[x] == belong[y]) {
        for(int i = x; i<=y; i++) {
            a[i]+=val;
        }
        rebuild(belong[x]);
        return ;
    }
    for(int i = x; i<=r[belong[x]]; i++) {
        a[i]+=val;
    }
    for(int i = l[belong[y]]; i<=y; i++) {
        a[i]+=val;
    }
    for(int i = belong[x]+1; i<belong[y]; i++) {
        add[i] += val;
    }
    rebuild(belong[x]);
    rebuild(belong[y]);
}
void bin(int x, ll val) {
    auto it = lower_bound(b[x].begin(), b[x].end(), mk(val, 0));
    if(it == b[x].end())
        return ;
    if(it->first == val) {
        ansx = min(ansx, it->second);
    }
    it = lower_bound(b[x].begin(), b[x].end(), mk(val+1, 0));
    if(it == b[x].begin())
        return ;
    it--;
    if(it -> first == val) {
        ansy = max(ansy, it->second);
    }
}
void query(ll val) {
    for(int i = 1; i<=cnt; i++) {
        ll tmp = val-add[i];
        if(tmp<0)
            continue;
        bin(i, tmp);
    }
}
int main()
{
    int q, x, y, z, sign;
    cin>>n>>q;
    block = sqrt(n*1.0);
    for(int i = 1; i<=n; i++) {
        scanf("%I64d", &a[i]);
        belong[i] = (i-1)/block+1;
    }
    if(n%block)
        cnt = n/block+1;
    else
        cnt = n/block;
    for(int i = 1; i<=cnt; i++) {
        l[i] = (i-1)*block+1;
        r[i] = i*block;
    }
    r[cnt] = n;
    for(int i = 1; i<=cnt; i++)
        rebuild(i);
    while(q--) {
        scanf("%d", &sign);
        if(sign == 1) {
            scanf("%d%d%d", &x, &y, &z);
            update(x, y, z);
        } else {
            scanf("%d", &x);
            ansx = inf, ansy = -inf;
            query(x);
            if(ansx==inf) {
                puts("-1");
            } else {
                printf("%d\n", ansy-ansx);
            }
        }
    }
    return 0;
}

 

posted on 2015-12-23 21:13  yohaha  阅读(261)  评论(0编辑  收藏  举报

导航