【uva 12003 Array Transformer】【分块】

来源:互联网 发布:屏蔽淘宝网 百度 编辑:程序博客网 时间:2024/05/22 03:16

题意:

给定一个序列,要求查询一个区间内有多少个数小于v。并且把第p个位置的值改为u * k / (R - L + 1)。

思路:

单点修改和区间查询。
线段树的话还要套平衡树,不会写,也不想写(:зゝ∠)

还是分块搞吧。。

把n个数分成 sqrt(n)个区间,然后把每个区间内都排序。
对于查询的时候,对于完全覆盖的块直接二分查,对于没完全覆盖的两端,直接暴力扫。

修改的时候,对于原数据直接改,对于排序后的要注意存的时候存上id,这样找出p在哪一块,直接覆盖掉,但是覆盖掉可能比原来的值大或者小,那么就直接交换到合适的位置就好了。

代码:

#include <set>#include <map>#include <queue>#include <vector>#include <math.h>#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using  namespace  std;#define ff first#define ss second#define pb push_back#define ll long long#define mod 1000000007#define ull unsigned long long#define mst(ss,b) memset(ss,b,sizeof(ss));#define pl(x) cout << #x << "= " << x << endl;const int inf = 0x3f3f3f3f;const int N = 3e5+5;int n, m, u;int num, blocks;ll ans[N], a[N];//num分块的个数//blocks表示块的大小struct node{    ll v;    int id;    node(int a = 0, int b = 0) {        v = a, id = b;    }    bool operator < (const node& rhs)const {        return v<rhs.v;    }};vector<node>q[1000];int query(int L, int R, int v){    int posL = (L-1)/blocks;    int posR = (R-1)/blocks;    if(posL == posR){        int k = 0;        for(int i=L; i<=R; i++)if(a[i] < v)k++;        return k;    }    int k = 0;    for(int i=L; i<=(posL+1)*blocks; i++)if(a[i] < v)k++;    for(int i=posR*blocks+1; i<=R; i++)if(a[i] < v)k++;    for(int i=posL+1; i<posR; i++)k += lower_bound(q[i].begin(), q[i].end(), v) - q[i].begin();    return k;}void update(int p, ll v){    a[p] = v;    int cur = (p-1)/blocks;    for(int i=0; i<q[cur].size(); i++){        if(q[cur][i].id == p){            if(q[cur][i].v == v)return ;            q[cur][i].v = v;            int pos = i;            while(pos > 0 && q[cur][pos].v < q[cur][pos-1].v){                swap(q[cur][pos], q[cur][pos-1]);                pos--;            }            while(pos < q[cur].size()-1 && q[cur][pos].v > q[cur][pos+1].v){                swap(q[cur][pos], q[cur][pos+1]);                pos++;            }            return ;        }    }}int  main(){    scanf("%d%d%d", &n, &m, &u);    blocks = sqrt(n);    for(int i=1; i<=n; i++){        scanf("%lld", &a[i]);        q[num].pb(node(a[i], i)); //        if(i/blocks != num)num++;    }    if(num * blocks != n)num++;    for(int i=0; i<num; i++)sort(q[i].begin(), q[i].end());    while(m--){        int L, R, v, p;        scanf("%d%d%d%d", &L, &R, &v, &p);        int k = query(L, R, v);        update(p, 1LL*u*k/(R-L+1));    }    for(int i=0; i<num; i++)        for(int j=0; j<q[i].size(); j++)ans[q[i][j].id] = q[i][j].v;    for(int i=1; i<=n; i++)printf("%lld\n", ans[i]);    return 0;}
0 0
原创粉丝点击