给两个长度为n的数组, 两种操作。
第一种, 给出x, y, k, 将a[x, x+k-1]这一段复制到b[y, y+k-1]。
第二种, 给出x, 输出b[x]的值。
线段树区间更新单点查询, 第一种操作, 就将线段树的[y, y+k-1]这一段赋值为i, i是第i个询问, 并将这个询问存到一个数组里。
第二种操作, 查询位置x处的值是多少, 做相应的修改就好..
感觉不是很难但还是写了好久
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 1e5+5; int sum[maxn<<2], cover[maxn<<2], a[maxn], b[maxn]; void pushDown(int rt) { if(cover[rt]) { if(cover[rt<<1]<cover[rt]) cover[rt<<1] = cover[rt]; if(cover[rt<<1|1]<cover[rt]) cover[rt<<1|1] = cover[rt]; cover[rt] = 0; } } void update(int L, int R, int val, int l, int r, int rt) { if(L<=l&&R>=r) { cover[rt] = val; return ; } pushDown(rt); int m = l+r>>1; if(L<=m) update(L, R, val, lson); if(R>m) update(L, R, val, rson); } int query(int p, int l, int r, int rt) { if(l == r) { return cover[rt]; } pushDown(rt); int m = l+r>>1; if(p<=m) return query(p, lson); else return query(p, rson); } pll q[maxn]; int main() { int n, m, x, y, k, sign; cin>>n>>m; for(int i = 1; i<=n; i++) scanf("%d", &a[i]); for(int i = 1; i<=n; i++) { scanf("%d", &b[i]); } for(int i = 1; i<=m; i++) { scanf("%d", &sign); if(sign == 2) { scanf("%d", &x); int tmp = query(x, 1, n, 1); if(tmp!=0) { y = q[tmp].se; b[x] = a[q[tmp].fi+x-y]; } printf("%d ", b[x]); } else { scanf("%d%d%d", &x, &y, &k); q[i] = mk(x, y); update(y, y+k-1, i, 1, n, 1); } } return 0; }