白皮书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 ",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 */
版权声明:本文博客原创文章,博客,未经同意,不得转载。