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
给定
看数据范围和题意不难想到,枚举
x123
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
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}给定两个长为
水题。最容易想到的是莫队,没什么可说的,但是写着麻烦。
简单思考一下可以想到类似双指针的写法,大概就是对于一个
然后有个人类智慧的写法就是随便实现一个满足交换律的哈希即可。
xxxxxxxxxx73123
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
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 : 0ll40 );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 : 0ll48 );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}给定凸包,逆时针给定凸包的每个顶点。你需要通过连结两个顶点将凸包划分为两部分并选择其中一个。令凸包面积为
发现这东西类似旋转卡壳,于是按照旋转卡壳的思想跑一下,或者说类似在环形上维护一个双指针,固定
xxxxxxxxxx74123
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
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);//2S29 }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]); //2S44 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。
xxxxxxxxxx158123
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;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,按秩合并会保证合并询问的时候不会复制太多次以保证空间。这个东西的复杂度理论上似乎可以被卡到
xxxxxxxxxx196123
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
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 初稿