AtCoder Beginner Contest 250 Solution更好的阅读体验戳此进入题面链接题面 Luogu 链接abc三道题太水了就跳了[ABC250D] 250-like Number题面SolutionCode[ABC250E] Prefix Equality题面SolutionCode[ABC250F] One Fourth题面SolutionCode[ABC250G] Stonks题面SolutionCode[ABC250Ex] Trespassing Takahashi题面SolutionCodeUPD
给定
看数据范围和题意不难想到,枚举
x1
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
25ll N;
26ll ans(0);
27basic_string < int > prime;
28bool notPrime[1100000];
29int sum[1100000];
30
31int main(){
32 N = read < ll >();
33 ll lim = (ll)powl(N, 1.0 / 3.0) + 10;
34 for(int i = 2; i <= lim; ++i){
35 if(!notPrime[i])prime += i;
36 for(auto p : prime){
37 if(i * p > lim)break;
38 notPrime[i * p] = true;
39 if(i % p == 0)break;
40 }
41 }for(int i = 2; i <= lim; ++i)sum[i] = sum[i - 1] + (!notPrime[i] ? 1 : 0);
42 for(auto p : prime){
43 ll base = (ll)p * p * p;
44 ans += sum[min(N / base, (ll)p - 1)];
45 }printf("%lld\n", ans);
46 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
47 return 0;
48}
49
50template < typename T >
51inline T read(void){
52 T ret(0);
53 int flag(1);
54 char c = getchar();
55 while(c != '-' && !isdigit(c))c = getchar();
56 if(c == '-')flag = -1, c = getchar();
57 while(isdigit(c)){
58 ret *= 10;
59 ret += int(c - '0');
60 c = getchar();
61 }
62 ret *= flag;
63 return ret;
64}
给定两个长为
水题。最容易想到的是莫队,没什么可说的,但是写着麻烦。
简单思考一下可以想到类似双指针的写法,大概就是对于一个
然后有个人类智慧的写法就是随便实现一个满足交换律的哈希即可。
xxxxxxxxxx
731
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
22
23
24template < typename T = int >
25inline T read(void);
26
27int N;
28int a[210000], b[210000];
29unll suma[210000], sumb[210000];
30unordered_set < int > exta, extb;
31
32int main(){
33 N = read();
34 for(int i = 1; i <= N; ++i){
35 a[i] = read();
36 suma[i] = suma[i - 1] ^ (
37 exta.find(a[i]) == exta.end()
38 ? exta.insert(a[i]), (unll)a[i] * (114514123ll)
39 : 0ll
40 );
41 }
42 for(int i = 1; i <= N; ++i){
43 b[i] = read();
44 sumb[i] = sumb[i - 1] ^ (
45 extb.find(b[i]) == extb.end()
46 ? extb.insert(b[i]), (unll)b[i] * (114514123ll)
47 : 0ll
48 );
49 }
50 int Q = read();
51 while(Q--){
52 int x = read(), y = read();
53 printf("%s\n", suma[x] == sumb[y] ? "Yes" : "No");
54 }
55 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
56 return 0;
57}
58
59template < typename T >
60inline T read(void){
61 T ret(0);
62 int flag(1);
63 char c = getchar();
64 while(c != '-' && !isdigit(c))c = getchar();
65 if(c == '-')flag = -1, c = getchar();
66 while(isdigit(c)){
67 ret *= 10;
68 ret += int(c - '0');
69 c = getchar();
70 }
71 ret *= flag;
72 return ret;
73}
给定凸包,逆时针给定凸包的每个顶点。你需要通过连结两个顶点将凸包划分为两部分并选择其中一个。令凸包面积为
发现这东西类似旋转卡壳,于是按照旋转卡壳的思想跑一下,或者说类似在环形上维护一个双指针,固定
xxxxxxxxxx
741
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
25struct Coord{
26 ll x, y;
27 friend const ll operator * (const Coord &a, const Coord &b){
28 return abs(a.x * b.y - a.y * b.x);//2S
29 }
30};
31ll CalS(Coord a, Coord b, Coord c){
32 Coord vec1{b.x - a.x, b.y - a.y}, vec2{c.x - a.x, c.y - a.y};
33 return vec1 * vec2;
34}
35Coord p[110000];
36int N;
37ll tot(0);
38ll ans(LONG_LONG_MAX);
39//abs(2A - 8B)
40int main(){
41 N = read();
42 for(int i = 1; i <= N; ++i)p[i].x = read(), p[i].y = read();
43 for(int i = 2; i <= N - 1; ++i)tot += CalS(p[1], p[i], p[i + 1]); //2S
44 int r(2);
45 ll cur(0);
46 for(int l = 1; l <= N; ++l){
47 while(cur * 4 < tot){
48 ans = min(ans, abs(tot - cur * 4));
49 cur += CalS(p[l], p[r], p[r % N + 1]);
50 (r %= N) += 1;
51 // printf("l = %d, r = %d, B = %lld, A = %lld\n", l, r, cur * 4, tot);
52 }ans = min(ans, abs(tot - cur * 4));
53 cur -= CalS(p[l], p[l + 1], p[r]);
54 // ans = min(ans, abs(tot - cur * 4));
55 }printf("%lld\n", ans);
56 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
57 return 0;
58}
59
60template < typename T >
61inline T read(void){
62 T ret(0);
63 int flag(1);
64 char c = getchar();
65 while(c != '-' && !isdigit(c))c = getchar();
66 if(c == '-')flag = -1, c = getchar();
67 while(isdigit(c)){
68 ret *= 10;
69 ret += int(c - '0');
70 c = getchar();
71 }
72 ret *= flag;
73 return ret;
74}
给定序列
明显反悔贪心。
不失一般性,令
双倍经验 CF865D Buy Low Sell High。
xxxxxxxxxx
1581
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;
26int P[210000];
27ll ans(0);
28priority_queue < pair < int, int >, vector < pair < int, int > >, greater < pair < int, int > > > cur;
29
30int main(){
31 N = read();
32 for(int i = 1; i <= N; ++i){
33 P[i] = read();
34 if(!cur.empty() && P[i] > cur.top().first){
35 int val, idx; tie(val, idx) = cur.top(); cur.pop();
36 ans += P[i] - val, cur.push({P[i], P[i]});
37 if(idx)cur.push({idx, 0});
38 }else cur.push({P[i], 0});
39 }printf("%lld\n", ans);
40 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
41 return 0;
42}
43
44template < typename T >
45inline T read(void){
46 T ret(0);
47 int flag(1);
48 char c = getchar();
49 while(c != '-' && !isdigit(c))c = getchar();
50 if(c == '-')flag = -1, c = getchar();
51 while(isdigit(c)){
52 ret *= 10;
53 ret += int(c - '0');
54 c = getchar();
55 }
56 ret *= flag;
57 return ret;
58}
给定一张 No
,反之输出 Yes
。保证询问中
考虑维护对于走每条边时需要多长时间才能连通最近的两个房子,换句话说,满足这个时间的时候这条边就一定可以被走。具体维护可以考虑建一个超级源点并向所有房子连个边,然后跑个 Dijk 即可,当然直接往队列里把所有房子点都塞进去也行。然后我们可以令
具体地,每次询问将边集里所有新的
同时不难想到即使
存在一道双倍经验 CF1253F Cheap Robot,略有区别,这里简单说一下:这道题的区别就在于询问的是最小的 clear()
之后 shrink_to_fit()
就会 TLE,否则会 MLE,按秩合并会保证合并询问的时候不会复制太多次以保证空间。这个东西的复杂度理论上似乎可以被卡到
xxxxxxxxxx
1961
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
25struct Edge{
26 Edge* nxt;
27 int to;
28 ll val;
29 OPNEW;
30}ed[410000];
31ROPNEW(ed);
32Edge* head[210000];
33
34int N, M, K;
35bitset < 210000 > vis;
36ll dis[210000];
37priority_queue < tuple < ll, int, int >, vector < tuple < ll, int, int > >, greater < tuple < ll, int, int > > > edgs;
38
39class UnionFind{
40private:
41 int fa[210000];
42public:
43 UnionFind(void){for(int i = 1; i <= 201000; ++i)fa[i] = i;}
44 int Find(int x){return x == fa[x] ? x : fa[x] = Find(fa[x]);}
45 void Union(int origin, int son){fa[Find(son)] = Find(origin);}
46}uf;
47
48void Dijk(void){
49 memset(dis, 0x3f, sizeof dis);
50 priority_queue < pair < ll, int >, vector < pair < ll, int > >, greater < pair < ll, int > > > cur;
51 for(int i = 1; i <= K; ++i)cur.push({dis[i] = 0, i});
52 while(!cur.empty()){
53 int p = cur.top().second; cur.pop();
54 if(vis[p])continue;
55 vis[p] = true;
56 for(auto i = head[p]; i; i = i->nxt)
57 if(dis[p] + i->val < dis[SON])
58 dis[SON] = dis[p] + i->val, cur.push({dis[SON], SON});
59 }
60}
61int main(){
62 N = read(), M = read(), K = read();
63 for(int i = 1; i <= M; ++i){
64 int s = read(), t = read(), v = read();
65 head[s] = new Edge{head[s], t, v};
66 head[t] = new Edge{head[t], s, v};
67 }Dijk();
68 for(int p = 1; p <= N; ++p)
69 for(auto i = head[p]; i; i = i->nxt)
70 edgs.push({i->val + dis[p] + dis[SON], p, SON});
71 int Q = read();
72 while(Q--){
73 int s = read(), t = read(); ll lim = read < ll >();
74 while(!edgs.empty() && get < 0 >(edgs.top()) <= lim)
75 uf.Union(get < 1 >(edgs.top()), get < 2 >(edgs.top())), edgs.pop();
76 printf("%s\n", uf.Find(s) == uf.Find(t) ? "Yes" : "No");
77 }
78 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
79 return 0;
80}
81
82template < typename T >
83inline T read(void){
84 T ret(0);
85 int flag(1);
86 char c = getchar();
87 while(c != '-' && !isdigit(c))c = getchar();
88 if(c == '-')flag = -1, c = getchar();
89 while(isdigit(c)){
90 ret *= 10;
91 ret += int(c - '0');
92 c = getchar();
93 }
94 ret *= flag;
95 return ret;
96}
update-2022_12_20 初稿