题意:输入n,q,输入n个数,q个查询
query(l,r)查询[l,r]区间的最小的
shift(i1,i2,i3,···,ik)
把i1位置的数改成a[i2],
a[i1]与a[i2]互换数值;
把i2位置上的数改成a[i3];
a[i2]与a[i3]互换数值
思路:裸线段树,竟然wa5次,错在了,update(1,b[k],a[b[k]]);一开始update(1,b[k],a[b[k-1]]),这是不对的,因为我已经把a[b[k]],与a[b[k-1]]互换数值了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100005;
int a[maxn];
struct Tree
{
int left,right,minn;
};
Tree tree[maxn<<2];
void build(int id,int l,int r)
{
tree[id].left=l;
tree[id].right=r;
if(l==r)
tree[id].minn=a[l];
else
{
int mid=(l+r)>>1;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
tree[id].minn=min(tree[id*2].minn,tree[id*2+1].minn);
}
}
void update(int id,int pos,int val)
{
if(tree[id].left==tree[id].right)
tree[id].minn=val;
else
{
int mid=(tree[id].left+tree[id].right)>>1;
if(pos<=mid)
update(id*2,pos,val);
else
update(id*2+1,pos,val);
tree[id].minn=min(tree[id*2].minn,tree[id*2+1].minn);
}
}
int query(int id,int l,int r)
{
if(tree[id].left==l&&tree[id].right==r)
return tree[id].minn;
else
{
int mid=(tree[id].left+tree[id].right)>>1;
if(r<=mid)
query(id*2,l,r);
else if(l>mid)
query(id*2+1,l,r);
else
return min(query(id*2,l,mid),query(id*2+1,mid+1,r));
}
}
int main()
{
int n,q,i,j,l,r,b[50],k,ans,t;
char s[50];
scanf("%d%d",&n,&q);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
while(q--)
{
//cin>>s;
scanf("%s",s);
if(s[0]=='q')
{
l=0;
r=0;
for(i=6;i<strlen(s);i++)
{
if(s[i]==',')
{
j=i+1;
break;
}
else
l=l*10+s[i]-'0';
}
for(;j<strlen(s);j++)
{
if(s[j]==')')
break;
r=r*10+s[j]-'0';
}
ans=query(1,l,r);
printf("%d\n",ans);
}
else
{
t=0;
k=0;
for(i=6;i<strlen(s);i++)
{
if(s[i]==',')
{
b[++k]=t;
t=0;
}
else if(s[i]==')')
{
b[++k]=t;
}
else
t=t*10+s[i]-'0';
}
for(i=1;i<=k-1;i++)
{
update(1,b[i],a[b[i+1]]);
t=a[b[i+1]];
a[b[i+1]]=a[b[i]];
a[b[i]]=t;
}
update(1,b[k],a[b[k]]);
}
}
}