给你n个数a[],给你q个操作,1操作,让l到r里的数都向前转一圈。l变成r,l+1变成l,l+2变成l+1。r变成r-1。如此变化。
2操作,反转l,r里的所有数。
问你m个数b[],求出变化后的a[bi]。
POINT:
虽然这题一开始很容易想到线段树,但其实一点关系都没有。一开始会想到按照q操作来巧妙的求出a[],但其实想不出。
因为m<=100,那么我们就来根据要求的a[bi],来推出他原来是什么a[ans]。
保存这q个操作,对每一个bi进行倒推,每次操作如果影响到了bi,就倒着模拟一次。因为每次操作只影响l到r的范围。所以bi在l-r之外的话就不用管。当然,这个bi是根据倒推的进程在变化的。
时间复杂度为m*q。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn = 200000+100;
int a[maxn];
int n,q,m;
int ans[111];
struct node
{
int kind;
int l,r;
}opt[maxn];
void doit(int temp,int now)
{
for(int i=q;i>=1;i--){
int k=opt[i].kind;
int l=opt[i].l;
int r=opt[i].r;
if(k==1){
if(l<=temp&&temp<=r){
temp--;
if(temp==l-1)
temp=r;
}
}
else{
if(l<=temp&&temp<=r){
int c=temp-l;
temp=r-c;
}
}
}
printf("%d",a[temp]);
}
int main()
{
scanf("%d %d %d",&n,&q,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
memset(ans,0,sizeof ans);
for(int i=1;i<=q;i++){
scanf("%d %d %d",&opt[i].kind,&opt[i].l,&opt[i].r);
}
for(int i=1;i<=m;i++){
if(i-1) printf(" ");
int a;
scanf("%d",&a);
doit(a,a);
}
printf("\n");
}