大白书上的393页。
一直在原数组上乱搞。其实要用另外一个数组记录块。
原数组是不能变的。
注意好原数组和块数组的关系,细心一点处理边界。还是不难的。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define maxn 300005 #define SIZE 600 using namespace std; int a[maxn]; int block[maxn]; int b[maxn]; void work(int p,int x) { int old=b[p]; b[p]=x; int BLOCK=p/SIZE; int pos=p; for(int i=BLOCK*SIZE;i<BLOCK*SIZE+SIZE;i++) { if(a[i]==old) { pos=i; a[i]=x; break; } } while(block[pos+1]==block[p] && a[pos+1]<a[pos]) { swap(a[pos+1],a[pos]); pos++; } while(pos-1>=0 && block[pos-1]==block[p] && a[pos-1]>a[pos]) { swap(a[pos-1],a[pos]); pos--; } } int main() { int n,m,u; while(scanf("%d%d%d",&n,&m,&u)!=EOF) { memset(a,0x3f,sizeof a); memset(block,0x3f,sizeof block); for(int i=0;i<n;i++) { scanf("%d",&a[i]); b[i]=a[i]; block[i]=i/SIZE; } for(int i=0;i<(n-1)/SIZE;i++) { sort(a+i*SIZE,a+(i+1)*SIZE); } sort(a+((n-1)/SIZE*SIZE),a+n); while(m--) { int l,r,v,p; scanf("%d%d%d%d",&l,&r,&v,&p); l--,r--,p--; int ans=0; if(block[l]==block[r]) { for(int i=l;i<=r;i++) if(b[i]<v)ans++; } else { for(int i=l;block[i]==block[l];i++) { if(b[i]<v)ans++; } for(int i=r;block[i]==block[r];i--) if(b[i]<v)ans++; for(int i=SIZE*(l/SIZE+1);i<r/SIZE*SIZE;i+=SIZE) { ans+=lower_bound(a+i,a+i+SIZE,v)-(a+i); } } work(p,(long long)u*ans/(r-l+1)); } for(int i=0;i<n;i++) printf("%d\n",b[i]); } return 0; } /* 10 3 5 10 9 8 7 6 5 4 3 2 1 2 5 9 4 2 9 6 5 4 10 5 6 */
uva 12003 Array Transformer (块状数组),布布扣,bubuko.com
uva 12003 Array Transformer (块状数组)
原文:http://blog.csdn.net/u010709592/article/details/37340047