社区讨论

求问

P9912[COCI 2023/2024 #2] Zatopljenje参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mk8a47pa
此快照首次捕获于
2026/01/10 20:26
2 个月前
此快照最后确认于
2026/01/13 21:45
2 个月前
查看原帖
这是我的 3030 分代码(TLE):CPP
#include <bits/stdc++.h>
#define ld p << 1
#define rd p << 1 | 1
using namespace std;
const int N = 2e5 + 5, M = 2e5 + 5;
inline int read(){
	int sum = 0;
	char ch = getchar();
	while(ch < '0' || ch > '9') ch = getchar();
	while(ch >= '0' && ch <= '9') sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
	return sum;
}
int n, a[N], Q, tot, ans[M];
struct wt{
	int l, r, x, wz;
} b[M];
bool cmp(wt t1, wt t2){
	return t1.x > t2.x;
}
struct Node2{
	int sz, id;
} tmp[N];
bool cmp2(Node2 t1, Node2 t2){
	return t1.sz > t2.sz;
}
struct Node{
	int l, r, sum;
	bool pl, pr;
} t[N << 2];
void push_up(int p){
	t[p].sum = t[ld].sum + t[rd].sum - (t[ld].pr && t[rd].pl);
	t[p].pl = t[ld].pl, t[p].pr = t[rd].pr;
}
void build(int p, int l, int r){
	t[p] = (Node) {l, r, 0, 0, 0};
	if(l == r) return;
	int mid = l + r >> 1;
	build(ld, l, mid);
	build(rd, mid + 1, r);
	push_up(p);
}
void upd(int p, int l){
	if(l <= t[p].l && t[p].r <= l){
		t[p].sum = 1, t[p].pl = t[p].pr = 1;
		return;
	}
	int mid = t[p].l + t[p].r >> 1;
	if(l <= mid) upd(ld, l);
	if(l > mid) upd(rd, l);
	push_up(p);
}
Node ask(int p, int l, int r){
	if(l <= t[p].l && t[p].r <= r){
		return t[p];
	}
	int mid = t[p].l + t[p].r >> 1;
	Node ans = {0, 0, 0, 0, 0};
	if(l <= mid) ans = ask(ld, l, r);
	if(r > mid){
		Node kr = ask(rd, l, r);
		if(ans.l == 0) ans = ask(rd, l, r);
		else ans = {ans.l, kr.r, ans.sum + kr.sum - (ans.pr && kr.pl), ans.pl, kr.pr};
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	n = read(), Q = read();
    build(1, 1, n);
	for(int i = 1;i <= n;i++) a[i] = read(), tmp[i] = {a[i], i};
	sort(tmp + 1, tmp + n + 1, cmp2);
	for(int i = 1;i <= Q;i++){
		b[i].l = read(), b[i].r = read(), b[i].x = read();
		b[i].wz = i;
	}
	sort(b + 1, b + Q + 1, cmp);
	for(int i = 1;i <= Q;i++){
		int l = b[i].l, r = b[i].r, x = b[i].x;
		while(tot < n && tmp[tot + 1].sz > x) tot++, upd(1, tmp[tot].id);
		ans[b[i].wz] = ask(1, l, r).sum;
	}
	for(int i = 1;i <= Q;i++) cout << ans[i] << "\n";
	return 0;
}
满分代码CPP
#include <bits/stdc++.h>
#define ld p << 1
#define rd p << 1 | 1
using namespace std;
const int N = 2e5 + 5, M = 2e5 + 5;
inline int read(){
	int sum = 0;
	char ch = getchar();
	while(ch < '0' || ch > '9') ch = getchar();
	while(ch >= '0' && ch <= '9') sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
	return sum;
}
int n, a[N], Q, tot, ans[M];
struct wt{
	int l, r, x, wz;
} b[M];
bool cmp(wt t1, wt t2){
	return t1.x > t2.x;
}
struct Node2{
	int sz, id;
} tmp[N];
bool cmp2(Node2 t1, Node2 t2){
	return t1.sz > t2.sz;
}
struct Node{
	int l, r, sum;
	bool pl, pr;
} t[N << 2];
Node operator + (Node t1, Node t2){
	return (Node) {t1.l, t2.r, t1.sum + t2.sum - (t1.pr && t2.pl), t1.pl, t2.pr};
}
void push_up(int p){
	t[p] = t[ld] + t[rd];
}
void build(int p, int l, int r){
	t[p] = (Node) {l, r, 0, 0, 0};
	if(l == r) return;
	int mid = l + r >> 1;
	build(ld, l, mid);
	build(rd, mid + 1, r);
	push_up(p);
}
void upd(int p, int l){
	if(l <= t[p].l && t[p].r <= l){
		t[p].sum = 1, t[p].pl = t[p].pr = 1;
		return;
	}
	int mid = t[p].l + t[p].r >> 1;
	if(l <= mid) upd(ld, l);
	if(l > mid) upd(rd, l);
	push_up(p);
}
Node ask(int p, int l, int r){
	if(l <= t[p].l && t[p].r <= r){
		return t[p];
	}
	int mid = t[p].l + t[p].r >> 1;
	if(r <= mid) return ask(ld, l, r);
	if(l > mid) return ask(rd, l, r);
	return ask(ld, l, r) + ask(rd, l, r);
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	n = read(), Q = read();
    build(1, 1, n);
	for(int i = 1;i <= n;i++) a[i] = read(), tmp[i] = {a[i], i};
	sort(tmp + 1, tmp + n + 1, cmp2);
	for(int i = 1;i <= Q;i++){
		b[i].l = read(), b[i].r = read(), b[i].x = read();
		b[i].wz = i;
	}
	sort(b + 1, b + Q + 1, cmp);
	for(int i = 1;i <= Q;i++){
		int l = b[i].l, r = b[i].r, x = b[i].x;
		while(tot < n && tmp[tot + 1].sz > x) tot++, upd(1, tmp[tot].id);
		ans[b[i].wz] = ask(1, l, r).sum;
	}
	for(int i = 1;i <= Q;i++) cout << ans[i] << "\n";
	return 0;
}
改动地方:仅仅增加了结构体重载运算和查询函数。
为什么时间优化了这么多?
仅仅是因为 3030 分代码常数过大吗?

回复

1 条回复,欢迎继续交流。

正在加载回复...