问题链接:UVA12299
题目大意:有两个操作,一个是循环转换,一个是区间查询最小值,让你完成这两个操作。
问题分析:涉及区间查询跟点修改,明显是线段树的题目了。。
代码实现:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100005;
struct node
{
int l, r, v;
}p[N<<2];
int shift[N];
void push_up(int k)
{
p[k].v = min(p[k<<1].v, p[k<<1|1].v);
}
void build(int l,int r,int k)
{
p[k].l = l, p[k].r = r;
if(l==r)
{
scanf("%d",&p[k].v);
return;
}
int mid = (l + r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
push_up(k);
}
void update(int l,int c,int k)
{
if(p[k].l==p[k].r)
{
p[k].v = c;
return;
}
int mid = (p[k].l+p[k].r)>>1;
if(l <= mid) update(l,c,k<<1);
else update(l,c,k<<1|1);
push_up(k);
}
int query(int l,int r,int k)
{
if(l <= p[k].l && p[k].r <= r)
return p[k].v;
int mid = (p[k].l + p[k].r) >> 1;
int ans = 0x3f3f3f3f;
if(l <= mid) ans = min(ans,query(l,r,k<<1));
if(r > mid) ans = min(ans,query(l,r,k<<1|1));
return ans;
}
int query_node(int l,int k)
{
if(p[k].l==p[k].r)
return p[k].v;
int mid = (p[k].l + p[k].r)>>1;
if(l <= mid) return query_node(l,k<<1);
else return query_node(l, k << 1|1);
}
int main()
{
int n,m,i,j,k,tmp;
scanf("%d%d",&n,&m);
build(1,n,1);
char s[100];
int a, b;
memset(s,0,sizeof(s));
for(i = 0; i < m; i++)
{
getchar();
scanf("%c%c%c%c%c%c",&s[0],&s[1],&s[2],&s[3],&s[4],&s[5]);
if(strcmp(s, "query(") == 0)
{
scanf("%d%c%d%c",&a,&s[0],&b,&s[0]);
printf("%d\n",query(a,b,1));
}
else
{
k = 0;
while(scanf("%d%c", &a,&s[0]),s[0] != ')')
shift[k++] = a;
shift[k++] = a;
tmp = query_node(shift[0],1);
for(j = 1; j < k; j++)
update(shift[j-1],query_node(shift[j],1),1);
update(shift[k-1],tmp,1);
}
}
}