线段树:n个数a[n],m个操作;
query(a,b):求a到b区间的最小值;
shift(……):shift里的数代表数组a的下标,把给定的下标的数向左移一位;
如:
7 5 6 2 4 8 5 1 4
shift(2,4,5,7)对应的数(2 8 5 4)
则数组变为:6 8 4 5 4 1 2;
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <string>
#define INF 999999999
int min[100005*4],Ad[100005];
int cont;
int Min(int a,int b)
{
if(a<b)
return a;
else
return b;
}
void build(int l,int r,int rt)
{
if(l==r)
{
min[rt]=Ad[l];
return;
}
int mid=(l+r)/2;
build(l,mid,rt*2);
build(mid+1,r,rt*2+1);
min[rt]=Min(min[rt*2],min[rt*2+1]);
}
int query(int l,int r,int L,int R,int rt)
{
if(l<=L && r>=R)
return min[rt];
int mid=(L+R)/2;
int ans=INF;
if(l<=mid)
ans=Min(ans,query(l,r,L,mid,rt*2));
if(r>mid)
ans=Min(ans,query(l,r,mid+1,R,rt*2+1));
return ans;
}
void update(int l,int r,int rt,int u,int v)
{
if(l==r)
{
min[rt]=v;
return;
}
int mid=(l+r)/2;
if(u<=mid)
update(l,mid,rt*2,u,v);
else
update(mid+1,r,rt*2+1,u,v);
min[rt]=Min(min[rt*2],min[rt*2+1]);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d",&Ad[i]);
build(1,n,1);
while(m--)
{
char ch[50];
scanf("%s",ch);
if(ch[0]=='q')
{
int a,b;
sscanf(ch+6,"%d,%d",&a,&b);
printf("%d\n",query(a,b,1,n,1));
}
else
{
int a[100];
int k=0;
for(int i=6;ch[i]!='\n';)
{
int x=0;
int j=i;
while(ch[j]!=',' && ch[j]!=')')
{
x=x*10+ch[j]-'0';
j++;
}
a[++k]=x;
if(ch[j]==')')
break;
else
i=j+1;
}
int p=query(a[1],a[1],1,n,1);//找出下标为a[1]的数 p
for(int i=1;i<k;i++)
{
int temp=query(a[i+1],a[i+1],1,n,1);//找出下标为a[i+1] 的数 temp
update(1,n,1,a[i],temp);//更新下标 a[i] 的数为 下标a[i+1]的数
}
update(1,n,1,a[k],p);//更新最后一位
}
}
}
return 0;
}