AtCoder Beginner Contest 258 Solution更好的阅读体验戳此进入题面链接题面 Luogu 链接abcd 跳了[ABC258E] Packing Potatoes题面SolutionCode[ABC258F] Main Street题面SolutionCode[ABC258G] Triangle题面SolutionCode[ABC258Ex] Odd Steps题面SolutionCodeUPD
给定序列
一道细节不少的找规律题。
首先不难发现,对于这个箱子,当你确定了从哪里开始装后,其最远能装到的位置也就确定了。我们考虑如何确定这个东西,不难想到做个前缀和然后二分,找到对应点开始的最长能取的长度,细节较多,如需要注意若长度仅为一初值需要判断。因为可能转回去所以可以将序列复制一份然后在这上面跑即可。
此时仍需要注意
复杂度卡在预处理上,最终复杂度
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}你要在平面直角坐标系中行走,每一步可以上下左右四个方向任意移动
显然可以选择直接走,或者走到起点附近的某个快速通道即终点附近的某个快速通道,共有
xxxxxxxxxx179123
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 B, K;26int Sx, Sy, Tx, Ty;27
28int main(){29 int T = read();30 while(T--){31 B = read(), K = read();32 Sx = read(), Sy = read(), Tx = read(), Ty = read();33 pair < int, int > S[10] = {34 {0, 0},35 {Sx / B * B, Sy},36 {Sx, int(ceil((double)Sy / B)) * B},37 {int(ceil((double)Sx / B)) * B, Sy},38 {Sx, Sy / B * B}39 };40 pair < int, int > T[10] = {41 {0, 0},42 {Tx / B * B, Ty},43 {Tx, int(ceil((double)Ty / B)) * B},44 {int(ceil((double)Tx / B)) * B, Ty},45 {Tx, Ty / B * B}46 };47 ll ans = ll(abs(Sx - Tx) + abs(Sy - Ty)) * K;48 for(int s = 1; s <= 4; ++s)49 for(int t = 1; t <= 4; ++t)50 ans = min(51 ans,52 abs(S[s].first - T[t].first) + abs(S[s].second - T[t].second) +53 (54 (ll)(abs(S[s].first - Sx) + abs(S[s].second - Sy)) * K +55 (ll)(abs(T[t].first - Tx) + abs(T[t].second - Ty)) * K56 )57 );58 printf("%lld\n", ans);59 }60
61 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);62 return 0;63}64
65template < typename T >66inline T read(void){67 T ret(0);68 int flag(1);69 char c = getchar();70 while(c != '-' && !isdigit(c))c = getchar();71 if(c == '-')flag = -1, c = getchar();72 while(isdigit(c)){73 ret *= 10;74 ret += int(c - '0');75 c = getchar();76 }77 ret *= flag;78 return ret;79}给你一个简单的无向图,其中有
求三角形
枚举 bitset 优化,最终复杂度
x
123
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;26ll ans(0);27bitset < 3100 > G[3100];28
29int main(){30 N = read();31 for(int i = 1; i <= N; ++i)for(int j = 1; j <= N; ++j){32 char c = getchar(); while(!isdigit(c))c = getchar();33 G[i][j] = c == '1' && j > i ? true : false;34 }35 for(int i = 1; i <= N; ++i)for(int j = i + 1; j <= N; ++j)36 if(G[i][j])ans += (G[i] & G[j]).count();37 printf("%lld\n", ans);38 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);39 return 0;40}41
42template < typename T >43inline T read(void){44 T ret(0);45 int flag(1);46 char c = getchar();47 while(c != '-' && !isdigit(c))c = getchar();48 if(c == '-')flag = -1, c = getchar();49 while(isdigit(c)){50 ret *= 10;51 ret += int(c - '0');52 c = getchar();53 }54 ret *= flag;55 return ret;56}给定
答案对
首先不考虑最后一个限制,则不难想到 DP,即设
然后发现转移为
边界为
然后复杂度是
矩阵快速幂优化即可。
然后对于第三个限制,我们只需要在维护的时候分段维护即可,每次维护到对应的
最终复杂度
xxxxxxxxxx182123
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
2223
24template < typename T = int >25inline T read(void);26
27int N;28ll S;29ll P[110000];30
31class Matrix3{32private:33public:34 ll v[3][3];35 Matrix3(ll v11 = 0, ll v12 = 0, ll v13 = 0, ll v21 = 0, ll v22 = 0, ll v23 = 0, ll v31 = 0, ll v32 = 0, ll v33 = 0){36 v[0][0] = v11, v[0][1] = v12, v[0][2] = v13,37 v[1][0] = v21, v[1][1] = v22, v[1][2] = v23,38 v[2][0] = v31, v[2][1] = v32, v[2][2] = v33;39 }40 friend const Matrix3 operator * (const Matrix3 &a, const Matrix3 &b){41 Matrix3 ret;42 for(int i = 0; i <= 2; ++i)for(int j = 0; j <= 2; ++j)for(int k = 0; k <= 2; ++k)43 (ret.v[i][j] += a.v[i][k] * b.v[k][j] % MOD) %= MOD;44 return ret;45 }46 friend const Matrix3 operator ^ (const Matrix3 &a, ll b){47 Matrix3 ret(1, 0, 0, 0, 1, 0, 0, 0, 1), mul(a);48 while(b){49 if(b & 1)ret = ret * mul;50 b >>= 1;51 mul = mul * mul;52 }return ret;53 }54};55
56int main(){57 N = read(), S = read < ll >();58 for(int i = 1; i <= N; ++i)P[i] = read < ll >();59 Matrix3 base(1, 1, 0, 0, 0, 1, 1, 1, 0);60 Matrix3 ans(1, 0, 0);61 for(int i = 1; i <= N; ++i)ans = ans * (base ^ (P[i] - P[i - 1])), ans.v[0][0] = 0;62 ans = ans * (base ^ (S - P[N]));63 printf("%lld\n", ans.v[0][0]);64 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);65 return 0;66}67
68template < typename T >69inline T read(void){70 T ret(0);71 int flag(1);72 char c = getchar();73 while(c != '-' && !isdigit(c))c = getchar();74 if(c == '-')flag = -1, c = getchar();75 while(isdigit(c)){76 ret *= 10;77 ret += int(c - '0');78 c = getchar();79 }80 ret *= flag;81 return ret;82}update-2022_12_17 初稿