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 补题报告2024年7月18日−2023年7月19日by 邓时飏
一、做题情况
-
第一题比赛 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
i−1个城市之间的距离(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
1≤n≤105
1
≤
a
i
,
m
≤
1
0
15
1 \le a_i,m \le 10^{15}
1≤ai,m≤1015
做法:
还挺简单的,就是要注意开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;
}
四、赛后总结
算法能力还有待加强,熟练度不高。