UVA12003.Array Transformer——分块

来源:互联网 发布:中银淘宝卡办理 编辑:程序博客网 时间:2024/06/14 21:29

http://www.bnuoj.com/v3/problem_show.php?pid=20421

题目分析:
输入一个数组A[1,…,n]和m条指令,你的任务是对数组进行变换,输出最终结果。每条指令形如(L,R,v,p),表示先统计出A[L],A[L+1],…,A[R]中严格小于v 的元素个数k,然后把A[p]修改成uk/(R-L+1)。这里的除法为整数除法

分析:
可以用嵌套数据结构
这里用分块

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>typedef long long LL;using namespace std;const int MAXN = 300010;const int SIZE = 4096;int n,m,u,a[MAXN],block[MAXN/SIZE+1][SIZE];void init(){    scanf("%d%d%d",&n,&m,&u);    int b=0,j=0;    for(int i=0;i<n;++i){        scanf("%d",&a[i]);        block[b][j++]=a[i];        if(j==SIZE){b++;j=0;}    }    for(int i=0;i<b;++i) sort(block[i],block[i]+SIZE);    if(j) sort(block[b],block[b]+j);//j==0没有block[b],否则有block[b]}int query(int L,int R,int v){    int lb=L/SIZE,rb=R/SIZE;    int k=0;    if(lb==rb){        for(int i=L;i<=R;++i){            if(a[i]<v) k++;        }    }else{        for(int i=L;i<(lb+1)*SIZE;++i){            if(a[i]<v) k++;        }        for(int i=rb*SIZE;i<=R;++i){            if(a[i]<v) k++;        }        for(int b=(lb+1);b<rb;++b){            k+=lower_bound(block[b],block[b]+SIZE,v)-block[b];        }    }    return k;}void change(int p,int x){    if(a[p]==x) return ;    int old=a[p],pos=0,*b=&block[p/SIZE][0];    a[p]=x;    while(b[pos]<old) pos++;b[pos]=x;    if(x>old)        while(pos<SIZE-1&&b[pos]>b[pos+1]){        swap(b[pos],b[pos+1]);        pos++;    }    else        while(pos>0&&b[pos]<b[pos-1]){        swap(b[pos],b[pos-1]);        pos--;    }}int main(){#ifndef ONLINE_JUDGEfreopen("in.cpp","r",stdin);#endif // ONLINE_JUDGE    init();    while(m--){        int L,R,v,p;        scanf("%d%d%d%d",&L,&R,&v,&p);        L--;R--;p--;        int k=query(L,R,v);        change(p,(LL)u*k/(R-L+1));    }    for(int i=0;i<n;++i) printf("%d\n",a[i]);//    cout<<"--------"<<endl;    return 0;}
0 0
原创粉丝点击