CSP - S 2024 模拟赛1补题报告

C S P   −   S    2024   模拟赛 1   补题报告 2024 年 7 月 18 日 − 2023 年 7 月 19 日 b y    邓时飏 CSP \ - \ S \ \ 2024 \ \ 模拟赛1 \ \ 补题报告 \\ 2024年7月18日 - 2023年7月19日 \\ by \ \ \ 邓时飏 CSP  S  2024  模拟赛1  补题报告20247182023719by   邓时飏

一、做题情况

  • 第一题比赛 20 20 20 / 100 100 100 ,赛后通过

  • 第二题比赛 0 0 0 / 100 100 100 ,赛后通过

  • 第三题比赛 0 0 0 / 100 100 100 ,赛后通过

  • 第四题比赛 0 0 0 / 100 100 100 ,赛后通过

  • 比赛得分 20 20 20 / 400 400 400 ,赛后补题 400 400 400 / 400 400 400

二、比赛概况

三、题解报告

T1:

题面:

题目描述
鱼大大计划环华夏自驾游游玩一圈,在他的计划中,这次旅行将在m天内完成,预计游玩n个城市,每个城市游玩x天,然后赶路开车以均速去到下一个城市,现鱼大大从海洋城市出发,按游玩顺序先后给出每个城市和上一个城市之间的距离(km),问鱼大大每天至少赶路多少距离(km)才能在m天内游玩所有城市?

输入格式
第一行两个数字 n , m n,m n,m;分别表示要游玩的城市数量和游玩天数
接下来 n n n行,每行两个整数 a i a_i ai , x x x a i a_i ai
表示第 i i i个城市和第 i − 1 i-1 i1个城市之间的距离(km); x x x表示在第i个城市游玩的时间(天); i = 1 i=1 i=1时为第一个游玩城市与鱼大大的出发地海洋城市的距离
注: 每天赶路的距离为整数

输出格式
一个整数表示鱼大大每天赶路的最少距离。如果无法再预计时间完成输出-1.

样例

Input 1
3 21
225 1
675 1
450 1
Output 1
75

样例解释
鱼大大从海洋城市出发,要在21天游玩完毕这3个城市。需每天最少赶路75km。
从海洋城市到第一城225km,需要赶路3天,游玩1天;
从第一城到第二城675km,需要赶路9天,游玩1天;
从第二城到第三城450km,需要赶路6天,游玩1天;
共21天。
若赶路距离再少,则无法在21天内完成。

数据范围
1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105
1 ≤ a i , m ≤ 1 0 15 1 \le a_i,m \le 10^{15} 1ai,m1015

做法:

还挺简单的,就是要注意开longlong

附:AC代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[100005],n,m,l=0,r=2e15;
bool check(int x){
	int ans=0;
	for(int i=1;i<=n;i++)
		ans+=ceil(a[i]*1.0/x);
	return ans<=m;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1,x;i<=n;i++){
		scanf("%lld%lld",&a[i],&x);
		m-=x;
	}
	while(l<r){
		int mid=l+r>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	printf("%lld",l==2e15?-1:l);
    return 0;
} 

T2:

题面:

做法:

附:AC代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=1e17;
const double eps=1e-6;
typedef unsigned long long ull;
typedef pair<ull,ull> pii;
int n;
ull a[500005];
ull b[500005];
pii dfs(int x){
    if(x==n) return make_pair(a[x],b[x]);
    pii num=dfs(x+1);
    ull p=a[x]*num.first+b[x]*num.second;
    ull q=a[x]*num.second;
    ull k=num.first*b[x];
    if(q>k) q-=k;
    else q=k-q;
    return make_pair(p,q);
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL),cout.tie(NULL);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++) 
        cin>>b[i];
    pii ans=dfs(1);
    cout<<ans.first<<' '<<ans.second;
    return 0;
}

T3:

题面:

做法:

附:AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef long double ld;
int n,fail[5000005],kas;
char s[5000005];
ull pw[5000005],ans[5000005],h1[5000005],h2[5000005];
ull gethsh(int i){
	return h1[i]*131+h2[i];
}
int main(){
	freopen("easy.in","r",stdin);
	freopen("easy.out","w",stdout);
	scanf("%s%d",s+1,&kas);
	n=strlen(s+1);
	pw[1]=131*131;
	h1[1]=h2[1]=s[1]-'a';
	ans[1]=gethsh(1);
	fail[0]=-1;fail[1]=0;
	for(int i=2,j=0;i<=n;i++){
		s[i]=(s[i]-'a'+int(ans[i-1]%26))%26+'a';
		while(~j&&s[j+1]!=s[i]) j=fail[j];
		fail[i]=++j;
		pw[i]=pw[i-1]*131*131;
		h1[i]=h1[i-1]*131*131+(s[i]-'a');
		h2[i]=h2[i-1]+(s[i]-'a')*pw[i-1];
		ans[i]=ans[fail[i]]+gethsh(i);
	}
	ull tmp=0;
	for(int i=1;i<=n;i++){
		tmp^=ans[i];
		if(i%kas==0) printf("%llu\n",tmp),tmp=0; 
	}
	return 0;
}

T4:

题面:

做法:



附:AC代码
#include <bits/stdc++.h>
#define ll long long
#define ls(p) p << 1
#define rs(p) p << 1 | 1
template < typename T > void read(T & x) {
    x = 0; int flag = 1; char c = getchar();
    for(; !isdigit(c); c = getchar()) if(c == '-') flag = -1;
    for(; isdigit(c); c = getchar()) x = x * 10 + c - '0';
    x *= flag;
}
using namespace std;
const int maxn = 100010;
int n, q, head[maxn], tot, pa[maxn][20], dep[maxn], lg[maxn];
ll dis[maxn];
struct Edge {
	int to, nxt, w;
} edge[maxn << 1];
struct Node {
	int l, r;
	ll sum;
} t[maxn << 2], res1, res2;
void add(int u, int v, int w) {
	edge[++ tot].to = v, edge[tot].w = w, edge[tot].nxt = head[u], head[u] = tot;
}
void dfs(int u, int fa) {
	for(int i = head[u]; i; i = edge[i].nxt) if(edge[i].to != fa) {
		int v = edge[i].to, w = edge[i].w;
		pa[v][0] = u, dep[v] = dep[u] + 1, dis[v] = dis[u] + w;
		dfs(v, u);
	}
}
int lca(int u, int v) {
	if(dep[u] < dep[v]) swap(u, v);
	int x = dep[u] - dep[v];
	while(x) u = pa[u][lg[x & -x]], x -= x & -x;
	if(u == v) return u;
	for(int k = min(lg[dep[u]], lg[dep[v]]); k >= 0; k --) if(pa[u][k] != pa[v][k]) u = pa[u][k], v = pa[v][k];
	return pa[u][0];
}
ll query(int x, int y) {
	return dis[x] + dis[y] - 2ll * dis[lca(x, y)];
}
void push_up(int p) {
	int a = t[ls(p)].l, b = t[ls(p)].r, c = t[rs(p)].l, d = t[rs(p)].r;
	t[p] = t[ls(p)].sum > t[rs(p)].sum ? t[ls(p)] : t[rs(p)];
	ll w1 = query(a, c), w2 = query(a, d), w3 = query(b, c), w4 = query(b, d);
	if(w1 > t[p].sum) t[p].sum = w1, t[p].l = a, t[p].r = c;
	if(w2 > t[p].sum) t[p].sum = w2, t[p].l = a, t[p].r = d;
	if(w3 > t[p].sum) t[p].sum = w3, t[p].l = b, t[p].r = c;
	if(w4 > t[p].sum) t[p].sum = w4, t[p].l = b, t[p].r = d;
}
void build(int p, int l, int r) {
	if(l == r) {
		t[p].l = t[p].r = l, t[p].sum = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(ls(p), l, mid), build(rs(p), mid + 1, r);
	push_up(p);
}
void query(int p, int l, int r, int ql, int qr, Node &res) {
	if(ql <= l && r <= qr) {
		if(!res.l) res = t[p];
		else {
			int a = res.l, b = res.r, c = t[p].l, d = t[p].r;
			if(t[p].sum > res.sum) res = t[p];
			ll w1 = query(a, c), w2 = query(a, d), w3 = query(b, c), w4 = query(b, d);
			if(w1 > res.sum) res.sum = w1, res.l = a, res.r = c;
			if(w2 > res.sum) res.sum = w2, res.l = a, res.r = d;
			if(w3 > res.sum) res.sum = w3, res.l = b, res.r = c;
			if(w4 > res.sum) res.sum = w4, res.l = b, res.r = d;
		}
		return;
	}
	int mid = (l + r) >> 1;
	if(ql <= mid) query(ls(p), l, mid, ql, qr, res);
	if(qr > mid) query(rs(p), mid + 1, r, ql, qr, res);
}
int main() {
	// scanf("%d %d", &n, &q);
	read(n), read(q);
	lg[1] = 0;
	for(int i = 2; i <= n; i ++) lg[i] = lg[i >> 1] + 1;
	for(int i = 1; i < n; i ++) {
		int u, v, w; read(u), read(v), read(w);
		add(u, v, w), add(v, u, w);
	}
	dfs(1, 0);
	for(int j = 1; j <= 16; j ++)
		for(int i = 1; i <= n; i ++)
			pa[i][j] = pa[pa[i][j - 1]][j - 1];
	build(1, 1, n);
	while(q --) {
		int l1, r1, l2, r2;
		//scanf("%d %d %d %d", &l1, &r1, &l2, &r2);
		read(l1), read(r1), read(l2), read(r2);
		res1.l = res1.r = res2.l = res2.r = 0, res1.sum = res2.sum = 0;
		query(1, 1, n, l1, r1, res1), query(1, 1, n, l2, r2, res2);
		printf("%lld\n", max(max(query(res1.l, res2.l), query(res1.l, res2.r)), max(query(res1.r, res2.l), query(res1.r, res2.r))));
	}
	return 0;
}

四、赛后总结

算法能力还有待加强,熟练度不高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值