题目链接:Codeforces 380A Sereja and Prefixes
题目大意:给出m次操作,分别有1:在序列最后加上x;2:复制1~x,y次,添加在序列尾部。然后给出n次查询,问说在第k[i]个位置上的数事多少。
解题思路:因为x不会大于10^5,就是说复制的部分最多就10^5,那么久可以在一开始将前10^5个数记录下来,后面只需要遍历n的同时移动m即可,但是字节很恶心,表示这辈子再也不想敲这种题了。
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; const int N = 100005; typedef long long ll; struct order { int s; ll x, y; }o[N]; int n, m, num[N], ans[N], c, cnt; ll k[N]; void handle () { c = 0; for (int i = 0; i < m; i++) { if (o[i].s == 1) { num[c++] = o[i].x; if (c >= 100000) return; } else { for (ll t = 0; t < o[i].y; t++) { for (ll j = 0; j < o[i].x; j++) { num[c++] = num[j]; if (c >= 100000) return; } } } } } void init () { scanf("%d", &m); for (int i = 0; i < m; i++) { scanf("%d", &o[i].s); if (o[i].s == 1) cin >> o[i].x; else cin >> o[i].x >> o[i].y; } handle(); scanf("%d", &n); for (int i = 0; i < n; i++) cin >> k[i]; } void solve () { int i = 0, j = 0; ll p = 0; while (i < n) { while (j < m) { if (o[j].s == 1) { p++; j++; if (p == k[i]) { ans[i] = o[j-1].x; i++; if (i >= n) return; break; } } else { ll q = p; p += o[j].x * o[j].y; if (p >= k[i]) { while (i < n) { if (k[i] <= p) { ans[i] = num[(k[i] - q - 1) % o[j].x % 100000]; i++; if (i >= n) return ; } else { j++; break; } } } else j++; } } } } int main () { init (); solve (); printf("%d", ans[0]); for (int i = 1; i < n; i++) printf(" %d", ans[i]); printf("\n"); return 0; }
Codeforces 380A Sereja and Prefixes(模拟)
原文:http://blog.csdn.net/keshuai19940722/article/details/19016703