题意:定义两种操作
- 1 a ---- 向序列中插如一个元素a
- 2 a b ---- 将序列的前a个元素[e1,e2,...,ea]重复b次插入到序列中
经过一列操作后,为处于某个位置p的元素是多少。数据范围共有105以内的操作,形成序列中的元素总个数大小不超过64bit长整型表示。
思考:只需要记录两种操作这些关键元素的位置,如果查询的坐标位置刚好是第一种产生的,那么直接就知道结果了;如果查询的是第二种操作产生的,它是由前a个元素重复b次而来,它来自前a个元素,依次递归向前找,直到找到第一种情况。
1 const int maxn = 100005; 2 __int64 pos[maxn]; 3 __int64 val[maxn]; 4 int flag[maxn];
可能用struct放到一起更直观一些。
flag用来标记,当前元素如果为1,则为第一种操作产生,pos此时记录当前元素位置,val记录当前元素的值。
flag为0时候,则为第二种操作产生,pos记录第二种操作开始的元素位置,val记录a,即序列的前a个元素,这个长度a。
知道这些我们就好办了,用二分,LowBound去找序列中查询元素位置在pos中的下界。然后根据flag来判断是否需要递归继续往下找,或是返回找到的结果。
1 __int64 GetResult(__int64 key) { 2 int l = 0, r = len-1; 3 while (l <= r) { 4 int m = (l+r) >> 1; 5 if (pos[m] == key) { 6 if (flag[m]) return val[m]; 7 else return GetResult((key-pos[m]+1)%val[m] != 0 ? ((key-pos[m]+1)%val[m]) : val[m]); 8 } else if (pos[m] < key) { 9 l = m+1; 10 } else { 11 r = m-1; 12 } 13 } 14 return GetResult((key-pos[r]+1)%val[r] != 0 ? ((key-pos[r]+1)%val[r]) : val[r]); 15 }
下面是完整代码:
1 #define _CRT_SECURE_NO_DEPRECATE 2 #define _SECURE_SCL 0 3 #pragma comment(linker, "/STACK:66777216") 4 #include <algorithm> 5 #include <string> 6 #include <complex> 7 #include <cassert> 8 #include <memory> 9 #include <set> 10 #include <stack> 11 #include <map> 12 #include <list> 13 #include <deque> 14 #include <numeric> 15 #include <cctype> 16 #include <cstddef> 17 #include <vector> 18 #include <queue> 19 #include <iostream> 20 #include <iomanip> 21 #include <iterator> 22 #include <cmath> 23 #include <cstdio> 24 #include <cstdlib> 25 #include <sstream> 26 #include <fstream> 27 #include <ctime> 28 #include <cstring> 29 #include <functional> 30 #include <bitset> 31 using namespace std; 32 33 #if defined(_MSC_VER) || defined(__BORLANDC__) 34 typedef unsigned __int64 uint64; 35 typedef signed __int64 int64; 36 #else 37 typedef unsigned long long uint64; 38 typedef signed long long int64; 39 #endif 40 typedef vector<int> VI; 41 typedef vector<string> VS; 42 typedef pair<int,int> PII; 43 typedef pair<int64,int64> PLL; 44 typedef vector<int64> VL; 45 46 #define pb push_back 47 #define ppb pop_back 48 #define mp make_pair 49 #define fi first 50 #define se second 51 #define pii pair<int,int> 52 #define pdd pair<double,double> 53 #define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++) 54 #define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--) 55 #define all(c) (c).begin(), (c).end() 56 #define SORT(c) sort(all(c)) 57 #define REP(i,n) FOR(i,1,(n)) 58 #define REPT(i,n) FOR(i,0,(n)-1) 59 #define L(s) (int)((s).size()) 60 #define C(a) memset((a),0,sizeof(a)) 61 #define IOS ios::sync_with_stdio(false) 62 63 const double pi = 3.1415926535897932384626433832795028841971; 64 const double EPS = 1E-9; 65 const int64 INF64 = (int64)1E18; 66 const int INF = 1000000000; 67 68 static inline bool get(int &v) { 69 int s = 1, c; 70 while(!isdigit(c = getchar())&&c != '-') 71 if(c == EOF) break ; 72 73 if(c == EOF) return 0; 74 if(c == '-') s = 0 , v = 0; 75 else v = c^48; 76 for(;isdigit(c = getchar());v = (v << 1) + (v << 3) + (c ^ 48)); 77 v = (s ? v : -v); 78 return 1 ; 79 } 80 int len = 0; 81 const int maxn = 100005; 82 __int64 pos[maxn]; 83 __int64 val[maxn]; 84 int flag[maxn]; 85 86 __int64 GetResult(__int64 key) { 87 int l = 0, r = len-1; 88 while (l <= r) { 89 int m = (l+r) >> 1; 90 if (pos[m] == key) { 91 if (flag[m]) return val[m]; 92 else return GetResult((key-pos[m]+1)%val[m] != 0 ? ((key-pos[m]+1)%val[m]) : val[m]); 93 } else if (pos[m] < key) { 94 l = m+1; 95 } else { 96 r = m-1; 97 } 98 } 99 return GetResult((key-pos[r]+1)%val[r] != 0 ? ((key-pos[r]+1)%val[r]) : val[r]); 100 } 101 102 103 void run() { 104 int m, n, op; 105 __int64 e, l, c, v = 1; 106 cin >> m; 107 FOR(i, 1, m) { 108 cin >> op; 109 if (op == 1) { 110 cin >> e; 111 pos[len] = v; 112 val[len] = e; 113 flag[len] = 1; 114 len += 1; 115 v++; 116 } else { 117 cin >> l >> c; 118 pos[len] = v; 119 val[len] = l; 120 flag[len] = 0; 121 v = l*c + pos[len]; 122 len += 1; 123 } 124 } 125 __int64 key; 126 cin >> n; 127 FOR(i, 1, n) { 128 cin >> key; 129 cout << GetResult(key) << " "; 130 } 131 cout << endl; 132 } 133 134 135 136 int main() { 137 #ifdef __DEBUG__ 138 freopen("test.in","r",stdin); 139 freopen("test.out","w",stdout); 140 time_t st = clock(); 141 #endif 142 run(); 143 #ifdef __DEBUG__ 144 printf( " ============= "); 145 printf("Time: %.2lf sec ",(clock()-st)/double(CLOCKS_PER_SEC)); 146 #endif 147 return 0; 148 }