给定序列
一道细节不少的找规律题。
首先不难发现,对于这个箱子,当你确定了从哪里开始装后,其最远能装到的位置也就确定了。我们考虑如何确定这个东西,不难想到做个前缀和然后二分,找到对应点开始的最长能取的长度,细节较多,如需要注意若长度仅为一初值需要判断。因为可能转回去所以可以将序列复制一份然后在这上面跑即可。
此时仍需要注意
复杂度卡在预处理上,最终复杂度
xxxxxxxxxx91123
45678910
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 初稿