给定序列
一道细节不少的找规律题。
首先不难发现,对于这个箱子,当你确定了从哪里开始装后,其最远能装到的位置也就确定了。我们考虑如何确定这个东西,不难想到做个前缀和然后二分,找到对应点开始的最长能取的长度,细节较多,如需要注意若长度仅为一初值需要判断。因为可能转回去所以可以将序列复制一份然后在这上面跑即可。
此时仍需要注意
复杂度卡在预处理上,最终复杂度
xxxxxxxxxx
911
2
3
4
5
6
7
8
9
10
11using namespace std;
12
13mt19937 rnd(random_device{}());
14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
15bool rnddd(int x){return rndd(1, 100) <= x;}
16
17typedef unsigned int uint;
18typedef unsigned long long unll;
19typedef long long ll;
20typedef long double ld;
21
22template < typename T = int >
23inline T read(void);
24
25int N, Q, X;
26int W[410000];
27ll sum[410000];
28int nxt[210000];
29ll siz[210000];
30ll lftans(0);
31bitset < 210000 > vis;
32int pos[210000];
33int mark[210000];
34int pre[210000];
35
36int main(){
37 // freopen("in.txt", "r", stdin);
38 N = read(), Q = read(), X = read();
39 for(int i = 1; i <= N; ++i)sum[i] = sum[i - 1] + (W[i] = read());
40 copy(W + 1, W + N + 1, W + N + 1);
41 for(int i = N + 1; i <= N << 1; ++i)sum[i] = sum[i - 1] + W[i];
42 ll tot = sum[N];
43 lftans += ll(X / tot) * N;
44 X %= tot;
45 if(!X)lftans -= N, X += tot;
46 for(int i = 1; i <= N; ++i){
47 int l = i, r = N << 1, ans(i - 1);
48 while(l <= r){
49 int mid = (l + r) >> 1;
50 if(sum[mid] - sum[i - 1] < X)ans = mid, l = mid + 1;
51 else r = mid - 1;
52 }nxt[i] = ans += 2;
53 siz[i] = lftans + (nxt[i] - i);
54 if(nxt[i] > N)nxt[i] -= N;
55 }
56 queue < int > path;
57 int cur = 1, len = 0;
58 while(!vis[cur]){
59 path.push(cur);
60 vis[cur] = true;
61 mark[++len] = cur;
62 cur = nxt[cur];
63 }int cnt(0);
64 while(path.front() != cur)pre[++cnt] = path.front(), path.pop();
65 len = 0;
66 while(!path.empty())pos[++len] = path.front(), path.pop();
67 pos[0] = pos[len];
68 while(Q--){
69 ll K = read < ll >();
70 if(K <= cnt)printf("%lld\n", siz[pre[K]]);
71 else printf("%lld\n", siz[pos[(K - cnt) % len]]);
72 }
73 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
74 return 0;
75}
76
77template < typename T >
78inline T read(void){
79 T ret(0);
80 int flag(1);
81 char c = getchar();
82 while(c != '-' && !isdigit(c))c = getchar();
83 if(c == '-')flag = -1, c = getchar();
84 while(isdigit(c)){
85 ret *= 10;
86 ret += int(c - '0');
87 c = getchar();
88 }
89 ret *= flag;
90 return ret;
91}
update-2022_12_13 初稿