2023 CSP 游记
前言
此乃小 Oler 的一篇比赛游记,从今日后,还会进行详细的修订。
注明:由于特殊原因,不能在考完试当天写下游记,深感遗憾。
Update \(2023-11-20\):出分数线了,才发现自己一波擦线双一流带走了...
考试前夜
“最后一晚了,背背模板”
背完若干模板...(考场上一个都没用到)
“早睡养精神,不行,必须熬夜,看看 NBA 勇士的新闻日先...”
\(10:00\) 关灯睡觉了好吧。
考试当天
早上 morning
正常起床,精神不错,浅浅发个动态“++RP”。
早餐,一碗面和八个饺子,嘴里喝着瓶奶就前往 smzx 考点,感觉风挺大的。
到了考点,只见 dalao myz 早已等候多时,便谁便聊起今年题目大概难度。
接着,各路 dalao 陆续到达,such as ljs , xzk , zsw , hk , lsy , yyh ...
和dalao们互相寒暄几句就进入试室。
普及组
\(8:27\) 解压文件夹,直接看题。
\(8:30\) 考试正式开始,当时做题顺序为 \(T1-T2-T4-T3\)。
T1 apple
做题时间段:\(8:30-9:00\)
所用时:约 \(30\) \(min\)
签到题必须拿下的好吧,第一眼按照做题思路,大概规律题,\(20\) \(min\) 没找出规律,看一眼时间,想先打个暴力再看,打完后发现可以直接过,复杂度竟然为 \(O(log_3 n)\),大样例也水过了,赶紧润。
考试期望值:\(+100pts\)
实际值:\(+100pts\)
T2 road
做题时间段:\(9:00-9:40\)
所用时:约 \(40\) \(min\)
看了题目像DP或贪心,再看数据范围 \(1e5\),暂时想不到怎么定义状态,就先放下DP,去想贪心。
我的贪心很简单想,边走边取最小值,然后计算其贡献,最后相加就行了,\(10\) \(min\) 打完。
这时候有趣的事情出现了,我按照题目顺序取大数据根本没注意题目的名字,取到了 bus 的大数据,绞尽脑汁调了 \(30\) \(min\) 才发现拿错了,怪不得找不出错...拿回原来的大数据,轻松就过了,时间复杂度为 \(O(n^2)\),为时不多了,赶紧润润润。
期望值:\(+100pts\)
实际值:\(+100pts\)
T3 uqe
做题时间段:\(10:30-11:57\)
所用时:约 \(90\) \(min\)
大模拟题,于是放到最后做,这时还剩 \(1h30min\),安心做题,慢慢地按照题目打,打完还剩 \(10\) \(min\),测试样例,结果错了几个,当我发现问题时,已经是 \(11:54\) 了,由于是 \(11:57\) 停止答题,只剩 \(3\) \(min\),心里慌得一批,改了一半,只能把半成品交了上去。
期望值:\(+50pts\)
实际值:\(+10pts\)
T4 bus
做题时间段:\(9:40-10:30\)
所用时:约 \(60\) \(min\)
考前估最后一题会是DP题,结果出了道最短路,当时第一反应是找出性质,再用 dijkstra 跑个最短路,我也找出了一小点的性质,就是所走的路径长度必须为 \(k\) 的倍数,可惜当时没有想到可以用分层图,随便打了个bfs暴力就润去做 T3。
期望值:\(+10pts\)
实际值:\(0pts\)
出了考场,脑子一片空白,听说很多大佬都做出了 \(3\) 题,myz和xzk都做完了(意料之中)。
而我这个蒟蒻只做了两题,第 \(3\) 题生死未卜...(自卑了)
中午 noon
在 smzx 食堂随便吃了午饭,和众dalao讨论,这才发现考试时没时间忘了新建文本文档和启动 NOI Linux 了,祭!
心态崩溃,回到阶梯室休息,幸亏有以前比赛的经验,也没多想,安稳入睡。
下午 afternoon
\(1:40\) 被叫醒,一脸朦胧上楼,还不能进考场,还有些时间,醒醒神,顺便膜拜 dalao,沾沾欧气。
\(2:05\) 进考场,坐在座位上向众神祈祷,回应我的只有...
提高组
上午考砸了,这一年的努力就靠这最后一场了,背水一战...
\(2:30\) 提高考试开始。
复原当时做题顺序为 \(T1-T2-T3-T4\),比较佛系的顺序...
T1 lock
做题时间段:\(2:30-3:00\)
所用时:约 \(30\) \(min\)
一开始认为第一题不会太过于简单,但又是第一题,也是要认真拿下的好吧,拿起草稿纸直接开始找性质,找半天发现数据范围 \(n\le 8\),而且密码锁只有五位,可以暴搜啊,一打还真可以,过来所有的样例,心里嘀咕着,咋还比普及 T1 还简单?(虽然我都因把题目想复杂而浪费时间了)
期望值:\(+100pts\)
实际值:\(+100pts\)
小插曲 I
T3题目样例解释有勘误,改正...(可惜我没怎么注意)
T2 game
做题时间段:\(3:00-3:20\)
所用时:约 \(20\) \(min\)
一眼盯真,有点像zsq总喜欢出的蓝题消融——区间DP,一看数据又把我吓了一跳,\(n\le 2\times 10^5\),这区间DP最多蹭个 \(35\) 分,看看还有没有其他方法。
突然想起考试前几天刷题时才看到大佬总结区间的题目可以先设 \(f_i\) 为开头或结尾定义状态,再浅浅结合题目,显然可以用 \(last_i\) 记录当前字符 \(i\) 其前面最后出现的位置,然后用栈维护,其实想到这时再坚持想想优化就可以对了,但当时脑子一傻,想不到怎么优化(失算了),只好打个 \(O(n^2)\),水个 \(50\) 分算了,程序很简单,\(10\) \(min\) 解决,然后就不管这题了,润润润。
期望值:\(+50pts\)
实际值:\(+50pts\)
T3 struct
做题时间段:\(3:20-4:55\)
所用时:约 \(100\) \(min\)
对于我来说的毒瘤大模拟,由于时间充足,所以想尽可能拿高分,开始时是直奔正解的,结果做了 \(40\) \(min\),我又不会了,一看特殊性质ABCD,好像把我打的程序改改后,正好都可以拿下,于是就转换方向,去考虑特殊性质,改了 大约 \(45\) \(min\),官方没有给出特殊性质的数据,只好自己做数据,用了 \(10\) \(min\) 就都过了,信心满满...可我忽视了一个很大的问题,就是考试时的题目有误,这边考场也是在开考后便立刻更改了勘误,而那时我在啃T1,后来也没多注意,也没怎么认真审题,按照样例解释打,最后导致爆 \(0\),哭死...
期望值:\(+80pts\)
实际值:\(0pts\)
自我感觉如果按照原来样例解释,这题起码都有四五十分,痛哭o(╥﹏╥)o
小插曲 II
时间段:\(4:55-5:05\)
所用时:约 \(10\) \(min\)
看着还剩一些时间到 \(5\) 点整,有了上午的经验,再加上中午请教 dalao,于是启动 NOI Linux,顺便写了个信息的文本文档,心里安稳些。
OK呀,NOI Linux上前三题程序都没有语法问题,那就赶紧去润T4。
T4 tree
做题时间段:\(5:05-6:20\)
所用时:约 \(80\) \(min\)
这一年来学得最多的知识点就是图论了,这不就来了一道图论题(可惜我不会)...
一开始还对这题报点希望,后知后觉,这道题不是现在的我可以拿下的,那只能看看特殊性质,特殊性质的图很容易画出来,觉得可以推推式子贪心或者直接遍历一边图拿部分分,可我想得太简单了,这道题的特殊性质也不好推,结果白白浪费了 \(1h20min\),最后只提交了一个暴力和两个特殊性质的错解(和普及组后两题的情况大差不差...)。
期望值:\([0,10]pts\)
实际值:\(0pts\)
其实感觉是做最后一题状态不好,不然也不至于一点部分分都拿不了。
小插曲 III
这下总有时间留下来回去检查了,检查无误后,坐在座位上,心里默默估着自己的分数和今年大概分数线。
\(6:27\) 考试结束,停止答题。
一天的考试终于结束了,清闲走出考场,天已经很暗了,这感觉和去年一样...
myz和ljs两位真神用了近 \(3h\) A了第二题,拿下了两题,必须膜拜的好吧。
晚上 evening
出门吃了餐好的,逛了 \(3h\) 商场,买了双新鞋(高兴...)
回到家,学校信息群已经热开了锅,接着便去估分...
赛后总结
普及J
考试预期分数:\(100+100+50+10=260\)
实际分数:\(100+100+10+0=210\)
只有二等了(差5分!!!),废了废了...
Upd:擦线一等啊...
首先是做题时的心态有点小问题,有可能是早上还没开智,状态不佳。
第一题开始的思考方向错误了,然后就是第二题拿错了大数据点,耗费了时间,这本是不应该出现的失误。
第三题赛后改了半个小时也没把原程序改出来,后来经过 hk 的讲解才知道是自己考试时想得太复杂了,而且没有化简就直接硬做,最后的结果也是重构代码...(即使第二题没拖时间,按照原来的程序照样也改不出来,该反思一番)
第四题考场时输出个 \(-1\) 也有 \(5\) 分,那样我就有一等了...(遗憾)
回归正题,第四题考场理论应该拿下的,考都考了,也是要分析一波原因的好吧,首先,dijkstra 是想到了,但是忘记了若遇到倍数的题,可以先往 \(%k\) 上想(由于考前做过倍数的题所总结的,结果考试忘了...),简单来说就是分层图...啊啊啊!!!
提高S
考试预期分数:\(100+50+80+[0,10]=230\)
实际分数:\(100+50+0+0=150\)
惊险擦线水个一等...(终于可以摆脱绿勾了)
一橙三蓝,理论阿克
第一题橙题半个小时切出来了(受到小小猜测提高组的难度导致),还能接受,不用多说...
第二题,可多要说了,这题其实可以用匹配栈和哈希做的,然而暑假刚好上过这个专题(虽然说没讲匹配栈),还是深有感触,挺可惜...
而第二题想到了另外一种正解的,可以优化过掉的,能想到是因为考前做过同类型的题目,也是看谋篇大神的题解的总结,但是没想到优化,为了保险起见,就只拿了 \(50pts\) 的点,考后经过 zsw 的分析,才明白怎么优化...(听说 myz,ljs 两位大佬就是没优化过的做法,而且还A了)
敲重点!!第三题由于个人太过沉迷于打大模拟中,结果忘了看勘误!!!
结果可想而知,\(80pts\to 0pts\),就当一次教训吧,警示自己...不想多说这道题了(大模拟)...
第四题又是可惜,不知道是因为什么原因,考场上写的 less,本是大根堆,结果程序总是输出小根堆的结果,自认为是自己程序的问题...痛失 \(25pts\to 0pts\)。(又又又听说 xzk 优先队列打对了,只拿了 \(5pts\),促使他痛失一等,惋惜...而大佬 ljs 不知为啥,思路差不多,听说考场不小心写挂了,也一分未得)
大总结
总结来说就是考试时傻了又傻,绝对不能轻易原谅自己!!!
还有考试心态和做题的策略很重要,归根结底就是平常练习习惯没养成,还是得从习惯抓起...
最重要的一点就是硬实力不行,学了的不会用,还得用功啊...
番外
还原考试程序
此部分可跳过,后面有蒟蒻写的题解。
注明:取自考试压缩包,没有删改痕迹...
普及组 210pts
T1 apple 100pts
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,t,ans,res=-1;
signed main() {
freopen("apple.in","r",stdin);
freopen("apple.out","w",stdout);
scanf("%lld",&n);
int x=n;
while(t!=n) {
int tem=(x-1)/3+1;
if(x%3==1&&res==-1)
res=ans+1;
t+=tem,x-=tem,ans++;
}
printf("%lld %lld\n",ans,res);
return 0;
}
T2 road 100pts
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,d,v[N],a[N];
signed main() {
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
scanf("%lld%lld",&n,&d);
for(int i=1;i<n;i++)
scanf("%lld",&v[i]);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
int ans=0,minx=a[1],p=v[1],t=0;
for(int i=2;i<n;i++) {
if(a[i]<minx) {;
ans+=minx*((p-t-1)/d+1);
int tem2=t;
t=((p-t-1)/d+1)*d+tem2-p;
minx=a[i];
p=0;
}
p+=v[i];
}
ans+=minx*((p-t-1)/d+1);
printf("%lld\n",ans);
return 0;
}
T3 uqe 10pts
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int t,m,a,b,c;
int pri[N];
map<int,int> mp;
signed main() {
freopen("uqe.in","r",stdin);
freopen("uqe.out","w",stdout);
scanf("%lld%lld",&t,&m);
for(int i=1;i<=m;i++)
pri[i]=i*i,mp[i*i]=i;
for(int i=1;i<=t;i++) {
scanf("%lld%lld%lld",&a,&b,&c);
int tem=b*b-4*a*c;
if(tem<0) printf("NO\n");
else {
int x1=(-b+sqrt(tem));
int x2=(-b-sqrt(tem));
// cout<<x1<<" "<<x2<<"\n";
if(x1>x2) {
int t=sqrt(tem);
if(t*t==tem) {
// cout<<-b+t<<"\n";
int p=-b+t,q=2*a;
int pp=p,qq=q;
if(p<0) p=-p;
if(q<0) q=-q;
int gc=__gcd(p,q);
p/=gc,q/=gc;
if(pp<0) p=-p;
if(qq<0) q=-q;
if(p==0) printf("0\n");
else if(q==1) printf("%lld\n",p);
else printf("%lld/%lld\n",p,q);
} else {
int p=-b,q=tem,x=0;
int pp=p,qq=q;
if(p<0) p=-p;
if(q<0) q=-q;
int gc=__gcd(p,a);
p/=gc;
gc=__gcd(q,a);
q/=gc;
if(pp<0) p=-p;
if(qq<0) q=-q;
for(int j=2;j<=sqrt(tem);j++)
if(tem%(j*j)==0)
x=j;
if(p==0) {
if(x==0) printf("sqrt(%lld)/2\n",q);
else {
if(x%2==0) printf("%lld*sqrt(%lld)\n",x/2,tem/x/x);
else {
if(x==1) printf("sqrt(%lld)/2\n",tem/x/x);
else printf("%lld*sqrt(%lld)/2\n",x,tem/x/x);
}
}
} else {
if(p%2==0) {
if(x==0) printf("%lld+sqrt(%lld)/2\n",p/2,q);
else {
if(x%2==0) printf("%lld+%lld*sqrt(%lld)\n",p/2,x/2,tem/x/x);
else {
if(x==1) printf("%lld+sqrt(%lld)/2\n",p/2,tem/x/x);
else printf("%lld+%lld*sqrt(%lld)/2\n",p/2,x,tem/x/x);
}
}
} else {
if(x==0) printf("%lld/2+sqrt(%lld)/2\n",p,q);
else {
if(x%2==0) printf("%lld+%lld*sqrt(%lld)/2\n",p,x/2,tem/x/x);
else {
if(x==1) printf("%lld/2+sqrt(%lld)/2\n",p,tem/x/x);
else printf("%lld/2+%lld*sqrt(%lld)/2\n",p,x,tem/x/x);
}
}
}
}
// printf("%lld/2+sqrt(%lld)/2\n",p);
}
} else {
int t=sqrt(tem);
if(t*t==tem) {
int p=-b-t,q=2*a;
int pp=p,qq=q;
if(p<0) p=-p;
if(q<0) q=-q;
int gc=__gcd(p,q);
p/=gc,q/=gc;
if(pp<0) p=-p;
if(qq<0) q=-q;
if(p==0) printf("0\n");
else if(q==1) printf("%lld\n",p);
else printf("%lld/%lld\n",p,q);
} else {
int p=-b,q=tem,x=0;
int pp=p,qq=q;
if(p<0) p=-p;
if(q<0) q=-q;
int gc=__gcd(p,a);
p/=gc;
gc=__gcd(q,a);
q/=gc;
if(pp<0) p=-p;
if(qq<0) q=-q;
for(int j=2;j<=sqrt(tem);j++)
if(tem%(j*j)==0)
x=j;
if(p==0) {
if(x==0) printf("sqrt(%lld)/2\n",q);
else {
if(x%2==0) printf("-%lld*sqrt(%lld)\n",x/2,tem/x/x);
else {
if(x==1) printf("-sqrt(%lld)/2\n",tem/x/x);
else printf("-%lld*sqrt(%lld)/2\n",x,tem/x/x);
}
}
} if(p%2==0) {
if(x==0) printf("%lld-sqrt(%lld)/2\n",p/2,q);
else {
if(x%2==0) printf("%lld-%lld*sqrt(%lld)\n",p/2,x/2,tem/x/x);
else {
if(x==1) printf("%lld-sqrt(%lld)/2\n",p/2,tem/x/x);
else printf("%lld-%lld*sqrt(%lld)/2\n",p/2,x,tem/x/x);
}
}
} else {
if(x==0) printf("%lld/2-sqrt(%lld)/2\n",p,q);
else {
if(x%2==0) printf("%lld-%lld*sqrt(%lld)/2\n",p,x/2,tem/x/x);
else {
if(x==1) printf("%lld/2-sqrt(%lld)/2\n",p,tem/x/x);
else printf("%lld/2-%lld*sqrt(%lld)/2\n",p,x,tem/x/x);
}
}
}
}
}
}
}
return 0;
}
/*
9 1000
1 -1 0
-1 -1 -1
1 -2 1
1 5 4
4 4 1
1 0 -432
1 -3 1
2 -4 1
1 7 1
*/
T4 bus 0pts
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int oo=0x3f3f3f3f;
const int N=1e5+10;
int n,m,k,x,y,z;
struct Node {
int to,nxt,st;
Node() {
to=nxt=st=0;
}
Node(int a,int b,int c) {
to=a;
nxt=b;
st=c;
}
} adj[N<<1];
int head[N],idx;
bool flag;
queue<int> a,b,c;
inline void add(int x,int y,int z) {
adj[++idx]=Node(y,head[x],z);
head[x]=idx;
}
void bfs(int s) {
a.push(s);
b.push(0);
c.push(0);
while(!a.empty()) {
int px=a.front(); a.pop();
int py=b.front(); b.pop();
int pz=c.front(); c.pop();
// cout<<px<<" "<<pz<<"\n";
if(px==n) {
if(pz%k==0) {
// cout<<py<<"\n";
printf("%lld\n",py+pz);
flag=1;
return ;
}
}
for(int i=head[px];i;i=adj[i].nxt) {
int v=adj[i].to,be=adj[i].st;
// if(pz+1>=be) {
// cout<<px<<" "<<v<<" "<<pz+1<<"\n";
// if(be==3) cout<<be-pz+1<<"\n";
a.push(v);
b.push(max(py,be-pz+1));
c.push(pz+1);
// }
}
}
}
signed main() {
freopen("bus.in","r",stdin);
freopen("bus.out","w",stdout);
scanf("%lld%lld%lld",&n,&m,&k);
cout<<n<<" "<<m<<"\n";
for(int i=1;i<=m;i++) {
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
}
bfs(1);
if(!flag) printf("-1\n");
return 0;
}
/*
5 5 3
1 2 0
2 5 1
1 3 0
3 4 3
4 5 1
*/
提高组 150pts
T1 lock 100pts
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[11],ans;
int s[11][6];
void dfs(int cnt) {
if(cnt>5) {
for(int i=1;i<=n;i++) {
int p=0;
for(int j=1;j<=5;j++) {
if(s[i][j]!=a[j]) {
if(p==1) {
if(s[i][j-1]!=a[j-1]) {
if((s[i][j-1]-a[j-1]+10)%10!=(s[i][j]-a[j]+10)%10)
return ;
} else return ;
}
p++;
if(p>2) return ;
}
}
if(p==0) return ;
}
ans++;
return ;
}
for(int i=0;i<=9;i++) {
a[cnt]=i;
dfs(cnt+1);
}
}
signed main() {
freopen("lock.in","r",stdin);
freopen("lock.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++) {
s[i][0]=-1;
for(int j=1;j<=5;j++)
cin>>s[i][j];
}
dfs(1);
printf("%lld\n",ans);
return 0;
}
T2 game 50pts
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int oo=0x3f3f3f3f;
const int N=1e5+10;
int n,f[N],last[30];
int stk[N],top,ans;
string s;
signed main() {
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
getline(cin,s);
int len=s.size();
for(int i=0;i<len;i++) {
if(s[i]>='0'&&s[i]<='9')
n=n*10+(s[i]-'0');
}
getline(cin,s);
len=s.size();
for(int i=0;i<=26;i++)
last[i]=oo;
for(int i=0;i<n;i++) {
if(last[s[i]-'a']!=oo) {
string w="";
top=0;
for(int j=last[s[i]-'a'];j<=n;j++) {
w+=s[j];
if(top&&s[j]==stk[top])
top--;
else stk[++top]=s[j];
if(top==0&&w!="")
ans++;
}
}
last[s[i]-'a']=i;
}
printf("%lld\n",ans);
return 0;
}
T3 struct 0pts
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1001;
int n,op,k,pos=1;
int maxv[N];
string s,t,a;
map<string,int> mp;
//map<string,int> mp3;
map<string,int> mp2;
map<int,string> mp4;
vector<string> vec[N];
int Vnum;
signed main() {
freopen("struct.in","r",stdin);
freopen("struct.out","w",stdout);
scanf("%lld",&n);
for(int i=1;i<=n;i++) {
cin>>op;
if(op==1) {
cin>>s>>k;
int maxx=0;
++Vnum;
vec[Vnum].push_back(s);
for(int j=1;j<=k;j++) {
cin>>t>>a;
if(t=="byte") {
maxx=max(1ll,maxx);
vec[Vnum].push_back(a);
} else {
if(t=="short") {
maxx=max(2ll,maxx);
vec[Vnum].push_back(a);
} else {
if(t=="int") {
maxx=max(4ll,maxx);
vec[Vnum].push_back(a);
} else {
if(t=="long") {
maxx=max(8ll,maxx);
vec[Vnum].push_back(a);
} else {
maxx=max(maxv[mp[t]],maxx);
vec[Vnum].push_back(a);
}
}
}
}
}
mp[s]=Vnum;
maxv[Vnum]=maxx;
}
if(op==2) {
cin>>t>>s;
if(t=="byte") {
mp2[s]=pos;
mp4[pos]=s;
pos++;
} else {
if(t=="short"){
mp2[s]=pos;
for(int j=pos;j<=pos+1;j++)
mp4[j]=s;
pos+=2;
} else {
if(t=="int") {
mp2[s]=pos;
for(int j=pos;j<=pos+3;j++)
mp4[j]=s;
pos+=4;
} else {
if(t=="long") {
mp2[s]=pos;
for(int j=pos;j<=pos+7;j++)
mp4[j]=s;
pos+=8;
} else {
int p=mp[t];
int len=vec[p].size();
int maxx=maxv[p];
for(int j=1;j<len;j++) {
mp2[s+'.'+vec[p][j]]=pos;
for(int ll=pos;ll<=pos+maxx-1;ll++)
mp4[ll]=s+'.'+ vec[p][j];
pos+=maxx;
}
}
}
}
}
}
if(op==3) {
cin>>s;
printf("%lld\n",mp2[s]-1);
}
if(op==4) {
cin>>k;
if(mp4[k+1]=="") printf("ERR\n");
else cout<<mp4[k+1]<<"\n";
}
}
return 0;
}
T4 tree 0pts
#include<bits/stdc++.h>
#define int long long
#define M(x,y) make_pair(x,y)
using namespace std;
typedef pair<int,int> pll;
const int N=1e5+10;
int n,x,y,a[N],b[N],c[N];
struct Node {
int to,nxt;
Node() {
to=nxt=0;
}
Node(int a,int b) {
to=a;
nxt=b;
}
} adj[N];
struct Tree {
int val,id;
} t[N];
int head[N],idx;
int dep[N],maxx[N];
int ans,w=0;
priority_queue<pll,vector<pll>,less<pll> > heap;
inline void add(int x,int y) {
adj[++idx]=Node(y,head[x]);
head[x]=idx;
}
void dfs(int u,int fa) {
dep[u]=dep[fa]+1;
for(int i=head[u];i;i=adj[i].nxt) {
int v=adj[i].to;
dfs(v,u);
}
}
void dfs2(int u,int fa) {
maxx[u]=t[u].val;
for(int i=head[u];i;i=adj[i].nxt) {
int v=adj[i].to;
dfs2(v,u);
maxx[u]=max(maxx[u],maxx[v]);
}
}
void dfs3() {
heap.push(M(t[1].val,1));
while(!heap.empty()) {
pll k=heap.top();
heap.pop();
int u=k.second;
int distance=k.first;
for(int i=head[u];i;i=adj[i].nxt) {
int v=adj[i].to;
w++;
ans=max(ans,t[v].val-dep[u]+w-1);
// cout<<w<<" "<<v<<" "<<t[v].val-dep[u]+w-1<<"\n";
heap.push(M(t[v].val,v));
}
}
}
signed main() {
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
int cnt=0;
bool flag=1;
for(int i=1;i<n;i++) {
scanf("%lld%lld",&x,&y);
if(y-x!=1) flag=0;
if(x==1) cnt++;
add(x,y);
}
if(flag) {
// cout<<n<<"\n";
int day=0,maxx=0;
for(int i=1;i<=n;i++) {
day++;
if(c[i]>0) {
int s=b[i]+c[i];
int m=a[i];
int g=c[i];
int ret=0;
if(g!=0) ret=(m-s-1)/g+1;
else ret=(m-s-1)+1;
if(ret*g<a[i]) ret++;
maxx=max(day+ret,maxx);
} else {
int ret=0,pp=0;
for(int j=1;;j++) {
ret+=max(1ll,b[i]+j*c[i]);
if(ret>=a[i]) {
pp=j;
break;
}
}
maxx=max(day+pp,maxx);
}
}
printf("%lld\n",maxx);
} else {
if(cnt==n-1) {
for(int i=2;i<=n;i++) {
if(c[i]>=0) {
t[i].val=111;
t[i].id=i;
} else ;
}
} else {
// cout<<111111<<"\n";
dfs(1,0);
for(int i=1;i<=n;i++) {
t[i].val=dep[i]+(a[i]-1)/b[i]+1;
t[i].id=i;
// cout<<t[i].val<<" ";
}
// cout<<"\n";
dfs2(1,0);
dfs3();
printf("%lld\n",ans);
}
}
return 0;
}
/*
4
5 1 0
8 2 0
3 1 0
11 2 0
1 2
1 3
3 4
*/
题解区
主要讲一下我没有水过的题目...
J-普及组
前两题已经水过了,不多说了,代码在上方...
T3
闲话:一道模拟题,虽说考场上没有做出来,但考后在 hk 的帮助下改出来了...
入正题,对于求解二元一次方程 \(ax ^ 2 + bx + c = 0, (a \neq 0)\),学过的都知道公式是这样的(题目也有说明):
可以对上面的式子进行化简,如下:
为了方便讨论,这里把 \(a\) 取正,即 \(a=|a|\)。
题目要求 \(x _ {1, 2}\) 两个实数解中的最大值,那若加必定可以使得解最大,那么只需要求解
现在就把问题转换为如何求解上式了,这里我们需要分类讨论了,不做赘述,大体是按输出形式分为两种情况,或是形如 \(a\),或是形如 \(a+b\) 的(此处的 \(a,b\) 都是实数)。
若是属于后一种情况,又需对实数中的有理数和无理数分别做处理即可,此处需要用到 gcd 等一类的操作。
这里重点说一下 \(\sqrt \Delta\) 怎么处理,首先判断 \(\Delta\) 是否是个完全平方数,如果是,那就直接开平方,若不是,则需要使之成为最简二次根式,上了初二的都会。简单说说,把 \(\Delta\) 化简后的答案分为有理数 \(y\) 和无理数 \(w\),还有除数 \(x\),输出 \(+ y \times sqrt(w) / x\) 即可。
详细见代码...
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int t,m,a,b,c,y,w;
signed main() {
// freopen("uqe.in","r",stdin);
// freopen("uqe.out","w",stdout);
scanf("%lld%lld",&t,&m);
for(int i=1;i<=t;i++) {
scanf("%lld%lld%lld",&a,&b,&c);
if(a<0) a=-a,b=-b,c=-c;
int tem=b*b-4*a*c;
int x=a*2,gc,cnt;
bool flag=1;
if(tem<0)
printf("NO\n");
else {
if(tem==0) {
if(b==0) printf("0\n");
else {
b=-b;
gc=__gcd(x,b);
x/=gc,b/=gc;
if(abs(x)==1) printf("%lld\n",x*b);
else {
if(x<0) x=-x,b=-b;
printf("%lld/%lld\n",b,x);
}
}
} else {
int t=sqrt(tem);
if(t*t==tem) {
b=-b+t;
gc=__gcd(x,b);
x/=gc,b/=gc;
if(abs(x)==1) printf("%lld\n",x*b);
else {
if(x<0) x=-x,b=-b;
printf("%lld/%lld\n",b,x);
}
} else {
if(b!=0) {
flag=0;
b=-b;
gc=__gcd(x,b);
x/=gc,b/=gc;
if(abs(x)==1) printf("%lld",x*b);
else {
if(x<0) x=-x,b=-b;
printf("%lld/%lld",b,x);
}
}
t=sqrt(tem),cnt=0;
y=w=1;
for(int i=2;i<=t;i++) {
while(tem%i==0) {
cnt++;
if(cnt==2)
y*=i,cnt=0;
tem/=i;
}
if(cnt==1) w*=i,cnt=0;
}
if(tem>1) w*=tem;
x=a*2;
gc=__gcd(y,x);
y/=gc,x/=gc;
y=abs(y),x=abs(x);
if(!flag) printf("+");
if(y!=1) printf("%lld*",y);
printf("sqrt(%lld)",w);
if(x!=1) printf("/%lld",x);
printf("\n");
}
}
}
}
return 0;
}
S-提高
T2
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;
int n,a[N][31],ans;
int last[N],f[N];
string s;
signed main() {
scanf("%lld",&n);
getchar();
getline(cin,s);
s=' '+s;
for(int i=1;i<=n;i++) {
last[i]=i;
int tem=a[last[i-1]][s[i]-'a'];
if(tem) {
last[i]=last[tem-1];
f[i]=f[tem-1]+1;
}
a[last[i]][s[i]-'a']=i;
ans+=f[i];
}
printf("%lld\n",ans);
return 0;
}