cf 板刷记录

CF1712E1 LCM Sum (easy version)

难度: 绿题

求 $ l< i < j < k < r, lcm(i, j, k) >= i + j + k $ 的数量。

考虑正难则反,用 \(C_{r-l+1}^{3}\) 减去 \(lcm(i, j, k) < i + j + k\) 的方案数即可。

因为 \(lcm(i, j, k)\) 一定是 \(k\) 的倍数,所以 \(lcm(i, j, k)\) 只有 \(k, 2k\) 两种情况。

我们考虑枚举一个 \(k\),然后 \(\mathcal{O}(\sqrt n)\) 分解质因数。

  • \(lcm(i, j, k) = k\)

\(i, j, k\) 的总方案数为 \(C_{cnt-1}^{2}\)\(cnt\)\(k\) 的质因数。

  • \(lcm(i, j, k) = 2k\)

只有 \((i, j, k)\)\((3, 4, 6)\) 或者 \((6, 10, 15)\) 的整数倍的时候才满足。

乘法的增加速度要大于加法的增加速度。

/**
 *	author: TLE_Automation
 *	creater: 2022.10.3
 **/
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
#define int long long
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

inline int C_2(int x) {
	return x * (x - 1) / 2; 
}

inline int C_3(int x) {
	return x * (x - 1) * (x - 2) / 6;
}

void Main() {
	int l = read(), r = read();
	ll ans = 0;
	for(int k = l; k <= r; k++) { 
		int cnt = 0;
		for(int i = 1; i * i <= k; i++) {
			if(k % i == 0) {
				int v1 = i, v2 = k / i, f(0);
				if(v1 >= l && v1 <= r) cnt++, f++;
				if(v2 >= l && v2 <= r) cnt++, f++;
				if(v1 == v2 && f == 2) cnt--;
			}	
		}
		ans += C_2(cnt - 1);
		if(k % 6 == 0 && k / 2 >= l) ans++;
		if(k % 15 == 0 && k * 2 / 5 >= l) ans++;
	}
	printf("%lld\n", C_3((r - l + 1)) - ans); 
}

/*
  1
  1 4
 */
signed main()
{
	int T = read();
	while(T--) Main();
	return (0 - 0);
}

CF1712D Empty Graph

难度:绿题

最小值最大,考虑二分。

这个直径显然最多只和两条边有关系。

我们二分一个最短距离,然后我们枚举两个点为 \(u, v\),且这两个点是相邻的,然后统计左右边 \(a_i \times 2< mid\) 的数量,以及这两个点 \(a_i < mid\) 的数量,和 \(k\) 做比较。

这个数量随便用个数据结构维护一下就行了吧。

/**
 *	author: TLE_Automation
 *	creater: 2022.10.4
 **/
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar 
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

int a[N];
const int M = 1e9;

namespace Seg {
	#define lson rt << 1
	#define rson rt << 1 | 1
	struct Node { int l, r, sum;} tree[N * 2];
	void build(int rt, int l, int r, int v) {
		tree[rt].l = l, tree[rt].r = r;
		if(l == r) return tree[rt].sum = (int)(a[l] * 2 < v), void();
		int mid = (l + r) >> 1;
		build(lson, l, mid, v), build(rson, mid + 1, r, v);
		tree[rt].sum = tree[lson].sum + tree[rson].sum;
	}
	int Query(int rt, int l, int r) {
		if(tree[rt].l > r || tree[rt].r < l) return 0;
		if(tree[rt].l >= l && tree[rt].r <= r) return tree[rt].sum;
		return Query(lson, l, r) + Query(rson, l, r);
	}
}
using namespace Seg;

int n, k;

bool Check(int mid) {
	build(1, 1, n, mid);
	int ans = 0x3f3f3f3f;
	for(int i = 1; i <= n - 1; i++)	ans = std::min(Query(1, 1, i - 1) + Query(1, i + 2, n) + (a[i] < mid) + (a[i + 1] < mid), ans);
	return ans <= k;
}

void Main() {
	n = read(), k = read();
	for(int i = 1; i <= n; i++) a[i] = read();
	int l = 1, r = M, ans(0);
	while(l <= r) {
		int mid = (l + r) >> 1;
		if(Check(mid)) ans = mid, l = mid + 1;
		else r = mid - 1;
	}
	printf("%d\n", ans);
}
signed main() 	
{
	int T = read();
	while(T--) Main();
	return (0 - 0);
}

CF1709D Rorororobot

难度:绿题

调到吐血。

啥也不想说了,直接放个代码吧。

/**
 *	author: TLE_Automation
 *	creater: 2022.10.51111
 **/
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

namespace Seg {
	#define mid ((l + r) >> 1)
	int Max[N << 2];
	void build(int rt, int l, int r) {
		if(l == r) return Max[rt] = read(), void();
		build(rt << 1, l, mid), build(rt << 1 | 1, mid + 1, r);
		Max[rt] = std::max(Max[rt << 1], Max[rt << 1 | 1]);
	}
	int Query(int rt, int l, int r, int L, int R) {
		if(l > R || r < L) return -0x3f3f3f3f;
		if(l >= L && r <= R) return Max[rt];
		return std::max(Query(rt << 1, l, mid, L, R), Query(rt << 1 | 1, mid + 1, r, L, R));
	}
}
using namespace Seg;

signed main()
{
	int n = read(), m = read();
	build(1, 1, m);
	int q = read();
	while(q--) {
		int sx = read(), sy = read(), ex = read(), ey = read(), k = read();
		int Maxn = (sx + ((n - sx) / k) * k);
		if(Maxn <= Query(1, 1, m, min(sy, ey), max(sy, ey)) || abs(sx - ex) % k || abs(ey - sy) % k != 0) {puts("NO"); continue;}
		puts("YES");		
	}	
	return (0 - 0);
}

CF17B Hierarchy

魔改一下最小生成树即可。

/**
 *	author: TLE_Automation
 *	creater: 2022.10.6
 **/
#include<tuple>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

int fa[N], q[N], n;
struct Edge {
	int u, v, w;
}e[N];

signed main()
{
	n = read();
	for(int i = 1; i <= n; i++) q[i] = read();
	int m = read();
	for(int i = 1; i <= m; i++)	e[i].u = read(), e[i].v = read(), e[i].w = read();
	sort(e + 1, e + m + 1, [](Edge a, Edge b) {return a.w < b.w; });
	int tot = 0, sum = 0;
	for(int i = 1; i <= m; i++) {
		if(q[e[i].u] > q[e[i].v] && !fa[e[i].v]) {
			fa[e[i].v] = e[i].u;
			tot++, sum += e[i].w;
 		}
 		if(tot == n - 1) break;
	}
	if(tot == n - 1) std::cout << sum << "\n";
	else std::cout << "-1" << "\n";
	return (0 - 0);
}

CF18C Stripe

前缀和,然后随便判断一下就行了。

/**
 *	author: TLE_Automation
 *	creater: 2022.10.6
 **/
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

int n, a[N], qzh[N];

signed main()
{
	int ans = 0;
	n = read();
	for(int i = 1; i <= n; i++) qzh[i] = qzh[i - 1] + read();
	for(int i = 1; i < n; i++) {
		if(qzh[n] - qzh[i] == qzh[i]) ans++;
	}
	std::cout << ans << "\n";
	return (0 - 0);
}

CF19A World Football Cup

简单小模拟,用 map 之后十分好做。

读入要用一些 c++ 的特性。

/**
 *	author: TLE_Automation
 *	creater: 2022.10.6
 **/
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

struct node { int num, reball, ball;};
std::map <string, node> mp;
string s[N], ans[N];

signed main()
{
	int n = read();
	for(int i = 1; i <= n; i++) cin >> s[i];
	for(int i = 1; i <= n * (n - 1) / 2; i++) {
		string t = "", t2 = "";
		getchar();
		char ch = getchar();
		while(ch != '-') t += ch, ch = getchar();
		cin >> t2;
		int x(0), y(0);
		cin >> x; getchar(); cin >> y;
		if(x == y) {
			mp[t].ball += x, mp[t2].ball += y;
			mp[t].num++, mp[t2].num++;
		}
		if(x > y) {
			mp[t].reball += x - y, mp[t].ball += x, mp[t2].ball += y, mp[t2].reball += y - x;
		 	mp[t].num += 3;
		}
		if(x < y) {
			mp[t2].reball += y - x, mp[t].ball += x, mp[t2].ball += y, mp[t].reball += x - y;
			mp[t2].num += 3;
		}
	}
	sort(s + 1, s + n + 1, [](string a, string b) {
			if(mp[a].num != mp[b].num) return mp[a].num > mp[b].num;
			else if(mp[a].reball != mp[b].reball) return mp[a].reball > mp[b].reball;
			else return mp[a].ball > mp[b].ball;
	});	
	for(int i = 1; i <= n / 2; i++) ans[i] = s[i];
	sort(ans + 1, ans + n / 2 + 1);
	for(int i = 1; i <= n / 2; i++) cout << ans[i] << "\n";
	return (0 - 0);
}

CF20C Dijkstra?

最短路的板子,注意开 long long

/**
 *	author: TLE_Automation
 *	creater: 2022.10.6
 **/
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
#define int long long
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

typedef pair <int, int> pil;
std::vector <pil> E[N];
priority_queue <pil, vector <pil>, greater <pil> > q;
std::bitset <N> vis;
int n, m, pre[N];
ll dis[N];

void Dijstra(int s) {
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[s] = 0, q.push(make_pair(0, s));
	while(!q.empty()) {
		int u = q.top().second; q.pop();
		if(vis[u]) continue; 
		vis[u] = 1;
		for(pair <int, int> it : E[u]) {
			int v = it.first, w = it.second;
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				if(!vis[v]) q.push(make_pair(dis[v], v));
				pre[v] = u;
			} 
		}
	}
}
int stc[N], sc = 0;
signed main()
{
	n = read(), m = read();
	for(int i = 1; i <= m; i++) {
		int u = read(), v = read(), w = read();
		E[u].push_back(make_pair(v, w));
		E[v].push_back(make_pair(u, w));
	}	
	Dijstra(1);
	if(dis[n] == inf)  return !printf("-1");
	for(int i = n; i; i = pre[i]) stc[++sc] = i;
	while(sc) printf("%lld ", stc[sc--]);
	return (0 - 0);
}

CF23A You're Given a String...

比题解更高深的做法?

哈希一下,然后枚举长度,取一段的哈希值,用 map 当桶存一下这个数的次数。

/**
 *	author: TLE_Automation
 *	creater: 2022.10.6
 **/
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

typedef unsigned long long ull;
const int base = 131;
ull Pow[N], Hash[N];
char s[N];
std::map <ull, int> mp;

inline ull Check(int l, int r) {
	return Hash[r] - Hash[l - 1] * Pow[r - l + 1];
}

signed main()
{
	scanf("%s", s + 1);
	int n = strlen(s + 1);	
	Pow[0] = 1;
	for(int i = 1; i <= n; i++) Pow[i] = Pow[i - 1] * base;
	for(int i = 1; i <= n; i++) Hash[i] = Hash[i - 1] * base + s[i];
	for(int len = n - 1; len >= 1; len--) {
		for(int l = 1; l + len - 1 <= n; l++) {
			mp[Check(l, l + len - 1)]++;
			if(mp[Check(l, l + len - 1)] == 2) return printf("%d\n", len), 0;
		}
	}
	printf("0");
	return (0 - 0);
}


posted @ 2022-10-03 19:49  TLE_Automation  阅读(27)  评论(0编辑  收藏  举报