题目大意
给两个数组,A 和 B,以及 m 个操作。每个数组中保存 n 个数,操作分两类:
1 x y k :把 A 数组中的 [x, x+k-1] 这个区间中的数复制到 B 数组中 [y, y+k-1] 去
2 x 询问 B 数组中,第 x 个数是多少
题目保证复制和查询操作是合法的
其中:1≤n,m≤105
做法分析
基础线段树,节点中保存的信息是:这一个区间是否被 A 数组覆盖,如果是,对应了 A 数组中的哪个区间,然后就是按照操作在线的模拟就行了
注意:
复制操作是后来居上的,会把全面的覆盖掉
如果当前点没有被覆盖,那么查询的时候输出的是 B 数组中原来在这个位置上的数,否则输出对应 A 数组中的数
参考代码
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 const int N=100006; 8 9 int A[N], B[N], n, m; 10 11 struct Interval_Tree 12 { 13 struct node 14 { 15 int s, t, bj, cs, ct; 16 void init(int a, int b) 17 { 18 s=a, t=b; 19 cs=ct=bj=0; 20 } 21 } T[N<<2]; 22 23 void build(int id, int L, int R) 24 { 25 T[id].init(L, R); 26 if(L==R) return; 27 int mid=(L+R)>>1; 28 build(id<<1, L, mid), build(id<<1|1, mid+1, R); 29 } 30 31 inline void pushDown(int id) 32 { 33 T[id<<1].cs=T[id].cs, T[id<<1|1].ct=T[id].ct; 34 int mid=(T[id].cs+T[id].ct)>>1; 35 T[id<<1].ct=mid, T[id<<1|1].cs=mid+1; 36 T[id].bj=0, T[id<<1].bj=1, T[id<<1|1].bj=1; 37 } 38 39 void update(int id, int L, int R, int x, int y) 40 { 41 if(L==T[id].s && T[id].t==R) 42 { 43 T[id].cs=x, T[id].ct=y; 44 T[id].bj=1; 45 return; 46 } 47 if(T[id].bj) pushDown(id); 48 int mid=(T[id].s+T[id].t)>>1; 49 if(R<=mid) update(id<<1, L, R, x, y); 50 else if(L>mid) update(id<<1|1, L, R, x, y); 51 else 52 { 53 update(id<<1, L, mid, x, x+mid-L); 54 update(id<<1|1, mid+1, R, x+mid-L+1, y); 55 } 56 } 57 58 int query(int id, int pos) 59 { 60 if(T[id].s==T[id].t) 61 { 62 if(T[id].bj) return T[id].cs; 63 else return -1; 64 } 65 if(T[id].bj) pushDown(id); 66 int mid=(T[id].s+T[id].t)>>1; 67 if(pos<=mid) return query(id<<1, pos); 68 else return query(id<<1|1, pos); 69 } 70 } tree; 71 72 int main() 73 { 74 scanf("%d%d", &n, &m); 75 for(int i=1; i<=n; i++) scanf("%d", &A[i]); 76 for(int i=1; i<=n; i++) scanf("%d", &B[i]); 77 tree.build(1, 1, n); 78 for(int i=0, t, x, y, k; i<m; i++) 79 { 80 scanf("%d", &t); 81 if(t==1) 82 { 83 scanf("%d%d%d", &x, &y, &k); 84 tree.update(1, y, y+k-1, x, x+k-1); 85 } 86 else 87 { 88 scanf("%d", &k); 89 x=tree.query(1, k); 90 if(x==-1) printf("%d\n", B[k]); 91 else printf("%d\n", A[x]); 92 } 93 } 94 return 0; 95 }