Problem Description:
You have an array consisting of n integers: a1=1,a2=2,a3=3,…,an=n. Then give you m operators, you should process all the operators in order. Each operator is one of four types:
Type1: O 1 call fun1();
Type2: O 2 call fun2();
Type3: O 3 call fun3();
Type4: Q i query current value of a[i], this operator will have at most 50.
Global Variables: a[1…n],b[1…n];
fun1() {
index=1;
for(i=1; i<=n; i +=2)
b[index++]=a[i];
for(i=2; i<=n; i +=2)
b[index++]=a[i];
for(i=1; i<=n; ++i)
a[i]=b[i];
}
fun2() {
L = 1;R = n;
while(L<R) {
Swap(a[L], a[R]);
++L;--R;
}
}
fun3() {
for(i=1; i<=n; ++i)
a[i]=a[i]*a[i];
}
Type1: O 1 call fun1();
Type2: O 2 call fun2();
Type3: O 3 call fun3();
Type4: Q i query current value of a[i], this operator will have at most 50.
Global Variables: a[1…n],b[1…n];
fun1() {
index=1;
for(i=1; i<=n; i +=2)
b[index++]=a[i];
for(i=2; i<=n; i +=2)
b[index++]=a[i];
for(i=1; i<=n; ++i)
a[i]=b[i];
}
fun2() {
L = 1;R = n;
while(L<R) {
Swap(a[L], a[R]);
++L;--R;
}
}
fun3() {
for(i=1; i<=n; ++i)
a[i]=a[i]*a[i];
}
Input:
The first line in the input file is an integer T(1≤T≤20), indicating the number of test cases.
The first line of each test case contains two integer n(0<n≤100000), m(0<m≤100000).
Then m lines follow, each line represent an operator above.
The first line of each test case contains two integer n(0<n≤100000), m(0<m≤100000).
Then m lines follow, each line represent an operator above.
Output:
For each test case, output the query values, the values may be so large, you just output the values mod 1000000007(1e9+7).
Sample Input:
1
3 5
O 1
O 2
Q 1
O 3
Q 1
Sample Output:
2
4
题意:给出三种操作,第一种是将奇数序的数提前,偶数序的数滞后,第二种是前后对称互换位置,第三种是每一位求取平方。
解题思路:
因为给定n和m都是100000,我们每一步都做具体的操作,时间将是O(n*m),肯定超时。最开始的时候
我怎么想都不知道怎么解决。以为是线段树。询问Q i最多50次。所以我们把每部的操作都记下来,每次Q i的时候,
就反推回去。自己可以推推。假设当前位置为x,我们要求操作之前的位置。
Fun1:
n = (n + 1) / 2;
x = x <= n / 2 ? (2 * x - 1) : ((x - n) * 2);
Fun2:
x = n + 1 - x;
Fun3:
我们用op记录平方次数。这样处理的时间复杂度O(50*n)。
#include<stdio.h> #include<string.h> #include<queue> #include<math.h> #include<stdlib.h> #include<algorithm> using namespace std; const int N=1e5+10; const int INF=0x3f3f3f3f; const int MOD=1e9+7; typedef long long LL; int a[N], ope[N], k; int Fun1(int x, int n) { n = (n+1)/2; if (x <= n) return 2*x-1; return (x-n)*2; } int Fun2(int x, int n) { return n+1-x; } void Solve(int x, int n) { int i, op = 0; LL num; for (i = k-1; i >= 0; i--) { if (ope[i] == 1) x = Fun1(x, n); else if (ope[i] == 2) x = Fun2(x, n); else op++; } num = x; for (i = 1; i <= op; i++) num = num * num % MOD; printf("%lld ", num); } int main () { int T, n, m, x, i; char s[10]; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); k = 0; for (i = 1; i <= n; i++) a[i] = i; while (m--) { scanf("%s %d", s, &x); if (s[0] == 'O') ope[k++] = x; else Solve(x, n); } } return 0; }