uva12299(线段树)

来源:互联网 发布:js n的阶乘 编辑:程序博客网 时间:2024/04/28 18:22

也是模板线段树.

只是需要对输入进行一些处理.

还有就是修改时候,不是普通的单点修改,要把shift里面的位置按顺序左移一位,第一个变成最后一个,第二个变成第一个.

用for来循环单点修改:


#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N = 100005;const int INF = 0x3f3f3f3f;int s[N << 2] ,lc[N << 2] ,rc[N << 2];int n,m,num[N];void build(int u ,int l ,int r) {lc[u] = l;rc[u] = r;if(l == r) {s[u] = num[l];return ;}int mid = (l + r) / 2;build(u * 2 , l , mid);build(u * 2 + 1 , mid + 1 ,r);s[u] = min(s[u * 2] , s[u * 2 + 1]);}void shift(int u , int x , int v) {if(lc[u] == x && rc[u] == x) {s[u] = v;return ;}int mid = (lc[u] + rc[u]) / 2;if(x <= mid)shift(u * 2 , x , v);elseshift(u * 2 + 1 , x , v);s[u] = min(s[u * 2] , s[u * 2 + 1]);}int query(int u , int l ,int r) {int res = INF;if(l <= lc[u] && r >= rc[u]) {return s[u];}int mid = (lc[u] + rc[u]) / 2;if(l <= mid) res = min(res , query(u * 2 , l , r));if(r > mid) res = min(res , query(u * 2 + 1 , l , r));return res;}int main() {scanf("%d%d",&n,&m);for(int i = 1; i <= n ; i++) {scanf("%d",&num[i]);}char str[35];build(1 , 1 , n);while(m--) {scanf("%s",str);if(str[0] == 'q') {int a[2] = {0};int j = 0;for (int i = 6 ; str[i] != ')' ;i++) {if(str[i] == ',') {j++;continue;}a[j] = (a[j] * 10) + str[i] - '0';}printf("%d\n",query(1 , a[0] , a[1]));}if(str[0] == 's') {int f[30] = {0};int k[30];int len = 0;for (int i = 6 ; str[i] != ')' ; i++) {if(str[i] == ',') {len++;continue;}f[len] = (f[len] * 10) + str[i] - '0';}int temp = num[f[0]];for (int i = 0 ; i < len ;i++) {shift(1 , f[i] , num[f[i + 1]]);num[f[i]] = num[f[i + 1]];}shift(1,f[len] , temp);num[f[len]] = temp;}}}


0 0
原创粉丝点击