题目描述 Description
hzwer找了一个人畜无害的迷の数列……
现在hzwer希望对这个数列进行一些操作,请你来回答hzwer的问题。
操作一:查询第i个数的大小
操作二:把第i个数的大小改成x
操作三:将整个序列反转。即把第i个数放到第n-i+1个。
输入描述 Input Description
输入数据第一行两个数n,m,表示数列长度和操作数。
第二行n个数,表示n个元素初始值。
以下m行,每行开头一个数opr,表示操作种类。
opr=1,则后面接一个数i,表示查询第i个数大小。
opr=2,则后面接两个数I,x,表示第i个数改成x。
opr=3,表示序列反转。
输出描述 Output Description
对于每个询问,输出答案。
样例输入 Sample Input
4 6
1 3 2 4
1 3
2 2 6
3
2 1 3
1 3
1 1
样例输出 Sample Output
2
6
3
数据范围及提示 Data Size & Hint
对于20%数据,1<=n,m<=10.
对于40%数据,1<=n,m<=100.
对于60%数据,1<=n,m<=1000.
对于100%数据,1<=n,m<=100000,1<=a[i]<=100000.
题意是一个数列支持单点修改、单点查询、区间[1,n]翻转
前两者显然数组就搞定
因为是整个区间翻转,所以可以直接用一个tag标记当前是不是翻转的,每次区间翻转后tag^=1,如果是翻转的只要把点的位置改成n-k+1,其他照旧即可。
一道NOIP普及组的送分题,如果这个分没有送到你的手上,2333
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 const int maxn=1000000; 5 bool fan=0; 6 int n,m,opr,a[maxn]; 7 int main(){ 8 scanf("%d%d",&n,&m); 9 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 10 for(int i=1;i<=m;i++) 11 { 12 scanf("%d",&opr); 13 if(opr==1) 14 { 15 scanf("%d",&opr); 16 if(fan)printf("%d ",a[n-opr+1]); 17 else printf("%d ",a[opr]); 18 } 19 else if(opr==2) 20 { 21 int l,x; 22 scanf("%d%d",&l,&x); 23 if(fan)a[n-l+1]=x; 24 else a[l]=x; 25 } 26 else if(opr==3)fan^=1; 27 } 28 }