- 题目
- 题意:query就是查询,shift( a, b, c)则是单点修改,将区间的a, b, c位置的值交换,即 a位置换成 b位置的值,b位置换成 c位置的值,c位置换成 a位置的值。
- 题解:只要理解了题意就是一道简单的单点修改,区间查询的线段树问题。
-
注意:字符串转化为数字的时候记得考虑是几位数,每次都当作个位数处理了(捂脸
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long const int maxn = 1e5 + 5, INF = 0x3f3f3f; using namespace std; struct node{ int mi; }tree[maxn * 4 + 10]; int pos[maxn], cnt = 0; void pushup(int p,int l,int r) { if(l < r){ tree[p].mi = min(tree[p << 1].mi, tree[p << 1 | 1].mi); } } void build(int l,int r,int p) { if(l == r){ scanf("%d",&tree[p].mi); pos[++cnt] = p; return ; } int mid = (l + r) >> 1; build(l,mid,p << 1); build(mid+1,r,p << 1 | 1); pushup(p,l,r); return; } void update(int nl,int nr,int px,int d,int p) { if(nl == nr) { tree[p].mi = d; return ; } int mid = (nl + nr) >> 1; if(px <= mid) update(nl, mid, px, d, p << 1); if(mid < px) update(mid+1, nr, px, d, p << 1 | 1); pushup(p,nl,nr); return; } LL query(int l, int r, int nl, int nr, int p) { if(nl >= l && nr <= r){ return tree[p].mi; } LL res = INF; int mid = (nl + nr) >> 1; if(l <= mid) res = min(res, query(l, r, nl, mid, p << 1)); if(mid < r) res = min(res, query(l, r, mid+1, nr, p << 1 | 1)); return res; } int main() { int n,q,num[maxn] = {0}; char str[maxn] = {0}; scanf("%d%d",&n,&q); build(1,n,1); while(q--) { scanf(" %s",str); if(str[0] == 'q') { int i = 6, j = 0; while(str[i]) { while(str[i] >= '0' && str[i] <= '9') { num[j] = num[j] * 10 + (str[i] - '0'); //记得乘10 ++i; } ++j;++i; } printf("%lld\n",query(num[0],num[1],1,n,1)); num[0] = 0, num[1] = 0; } else { int i = 6, j = 1; while(str[i]) { while(str[i] >= '0' && str[i] <= '9'){ num[j] = num[j] * 10 + (str[i] - '0'); ++ i; } ++ i; ++ j; } int mark = tree[pos[num[1]]].mi; for(int i = 1; i < j; ++ i) { update(1,n,num[i],tree[pos[num[i+1]]].mi,1); } update(1,n,num[j-1],mark,1); memset(num,0,sizeof(num)); } } return 0; }
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交