uva12003 - Array Transformer 分块结构
来源:互联网 发布:阿里巴巴上架软件 编辑:程序博客网 时间:2024/05/21 06:45
Write a program to transform an array A[1], A[2], . . . , A[n] according to m instructions. Each instruction(L, R, v, p) means: First, calculate how many numbers from A[L] to A[R] (inclusive) are strictly lessthan v, call this answer k. Then, change the value of A[p] to u ∗ k/(R − L + 1), here we use integerdivision (i.e. ignoring fractional part).InputThe first line of input contains three integer n, m, u (1 ≤ n ≤ 300, 000, 1 ≤ m ≤ 50, 000, 1 ≤ u ≤1, 000, 000, 000). Each of the next n lines contains an integer A[i] (1 ≤ A[i] ≤ u). Each of the nextm lines contains an instruction consisting of four integers L, R, v, p (1 ≤ L ≤ R ≤ n, 1 ≤ v ≤ u,1 ≤ p ≤ n).OutputPrint n lines, one for each integer, the final array.Sample Input10 1 11123456789102 8 6 10Sample Output1234567896Explanation: There is only one instruction: L = 2, R = 8, v = 6, p = 10. There are 4 numbers(2,3,4,5) less than 6, so k = 4. The new number in A[10] is 11 ∗ 4/(8 − 2 + 1) = 44/7 = 6.
输入N(1<=N<=300000),M(1<=M<=50000),U(1<=U<=10^9),接下来输入数组a(N个数),M次操作,每次操作输入L,R,V,P,计算出[L,R]区间内小于V的数的个数k,把A[P]修改为U*k/(R-L+1)。最后输出M次操作后的数组。
把数组分块,每块大小在根号N附近(这样比较快),对每块排序,这样每次询问L,R的时候在L,R所在的块进行暴力查找,L,R之间的块用二分查找。修改的时候不光要修改原数组,还要修改分块数组,找到P所在的块,然后找到要修改的值所在的位置,把这个位置替换为新值,再维护块内的顺序。找L,R所在块的位置很好找,因为是按顺序分的,所以直接用位置除以块大小就是块编号。
分块法其实也就是划分成小范围的暴力,这里如果块大小取根号N的话,复杂度O(M*√N*log√N), 白书上说分块法非常有用,很多用伸展树或树套树能解决的问题用分块法。
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef long long LL;const int MAXN=300010;const int SIZE=4096;const int INF=0x3f3f3f3f;int N,M,U,L,R,V,P;int a[MAXN],block[MAXN/SIZE+1][SIZE];int query(int l,int r,int v){ int lb=l/SIZE,rb=r/SIZE; int ret=0; if(lb==rb){ for(int i=l;i<=r;i++) if(a[i]<v) ret++; } else{ for(int i=l;i<(lb+1)*SIZE;i++) if(a[i]<v) ret++; for(int i=rb*SIZE;i<=r;i++) if(a[i]<v) ret++; for(int i=lb+1;i<rb;i++) ret+=lower_bound(block[i],block[i]+SIZE,v)-block[i]; } return ret;}void change(int p,int x){ if(a[p]==x) return; int old=a[p],pos=0,*b=block[p/SIZE]; 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+1],b[pos]); pos++; } } else{ while(pos>0&&b[pos]<b[pos-1]){ swap(b[pos-1],b[pos]); pos--; } }}int main(){ freopen("in.txt","r",stdin); while(scanf("%d%d%d",&N,&M,&U)!=EOF){ 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); while(M--){ 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]); } return 0;}
- uva12003 - Array Transformer 分块结构
- uva12003 Array Transformer 分块
- UVA12003.Array Transformer——分块
- UVA 12003 Array Transformer [分块]
- 【uva 12003 Array Transformer】【分块】
- uva 12003 - Array Transformer(分块+树套树)
- 【分块】UVA 12003 Array Transformer 水题
- UVA 12003Array Transformer (分块)
- UVA 12003 Array Transformer (分块)
- uvaoj 12003 - Array Transformer
- UVA 12003Array Transformer(树套树)
- uva 12003 Array Transformer (块状数组)
- byte-array-to-string-transformer 作用
- Transformer
- 数组分块(array chuncking)
- Codeforces 86D Powerful array 分块
- codeforces 86D. Powerful array(分块)
- 2016-scut-H. Lucky Array(分块)
- Android设计模式学习之单例模式
- Unsupported major.minor version 51.0 错误处理
- 异步传输图片到后台处理
- Xcode修改工程名字
- dfdafadsfefgvdfgbt
- uva12003 - Array Transformer 分块结构
- JAVA抽奖的算概率法
- Java执行操作系统命令
- iOS学习之iOS沙盒(sandbox)机制和文件操作(一)
- RS232芯片好坏判断
- NSUserDefaults 简介,使用 NSUserDefaults 存储自定义对象
- Testin发布Pre.im打造中国版TestFlight
- Java可变类与不可变类
- GRE写作必备句型