原题
其实只要记住一点,若要改变2个位置(l,r)的数值。那么影响的,是l,是r,是a[pos]=l的pos,是a[pos]=r的pos。一共4个值。所以用一个b数组来存(例如,位置k被换了,那么影响的是a[pos]=k的pos,而b数组来存b[k]=pos),
#include<bits/stdc++.h>
#define lson k<<1,l,mid
#define rson k<<1|1,mid+1,r
#define ll long long
using namespace std;
const int MX=1e5+9;
int T,n,m,order,l,r,laze;
ll t[MX<<2];
int a[MX],b[MX];
ll ans;
void build(int k,int l,int r){
if( l==r ){
t[k]=1ll*a[a[l]];
return ;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
t[k]=t[k<<1]+t[k<<1|1];
}
void update(int k,int l,int r,int pos){
if( l==r ){
t[k]=1ll*a[a[l]];
return ;
}
int mid=(l+r)>>1;
if( pos<=mid )
update(lson,pos);
else
update(rson,pos);
t[k]=t[k<<1]+t[k<<1|1];
}
void que(int k,int l,int r,int L,int R){
if( L<=l && r<=R ){
ans+=t[k];
return ;
}
int mid=(l+r)>>1;
if( L<=mid )
que(lson,L,R);
if( mid<R )
que(rson,L,R);
}
int main()
{
freopen("input.txt","r",stdin);
scanf("%d",&T);
while( T-- ){
scanf("%d",&n);
for( int i=1 ; i<=n ; i++ )
scanf("%d",&a[i]),b[a[i]]=i;
build(1,1,n);
scanf("%d",&m);
while( m-- ){
scanf("%d %d %d",&order,&l,&r);
if( order==1 ){
swap(a[l],a[r]);
b[a[l]]=l; // a[l]与a[r]互换时,记得b也要互换
b[a[r]]=r;
update(1,1,n,l);
update(1,1,n,r);
update(1,1,n,b[l]);
update(1,1,n,b[r]);
}
else{
ans=0;
que(1,1,n,l,r);
printf("%lld\n",ans);
}
}
}
return 0;
}