标签:
解题思路:
因为给定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\n", 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; }
HDU 5063 Operation the Sequence(BestCoder Round #13)
标签:
原文地址:http://www.cnblogs.com/syhandll/p/4928255.html