这个人 CSP-S 接近保单,NOIP 没参加,所以自然参加不了省选,只能打 abc 涨信心。
19:00
赛前看个新闻联播,放松身心~
19:38
赛前想做出来 P10143,结果发现实力不允许。
20:00
启动!
20:01 A题
ABC 特产,A题一眼得不能再一眼,但我事先没有打开翻译软件,寄飞了……开赛两分半才做出 A 题
20:03 B题
直接做题,甚至都不用开数组,直接输入的时候输出……
20:06 干出来了。
20:06 C题
这个翻译软件我服了啊,多出来这么多换行,害得我改格式改了五分钟。
然后我又看了五分钟的题目,发现 n ≤ 1 0 18 n \leq 10^{18} n≤1018,看上去很唬人,但实际上答案是 1 0 6 10^6 106 以内的某个数的完全立方数,直接枚举底数就行了,判断回文数也十分简单粗暴,用数组记录每一位就行了。至于答案上界,就是 n 3 \sqrt[3]{n} 3n,可以直接用二分法求。
时间复杂度: O ( n 3 log 10 n ) O(\sqrt[3]{n} \log_{10}{n}) O(3nlog10n)。
代码
#include <cstdio>
using namespace std;
long long n,l,r,mid;
int a[20],tot;
bool hui(long long p){
tot=0;
while(p)a[++tot]=p%10,p/=10;
for(int i=1;i<=tot>>1;++i)if(a[i]!=a[tot-i+1])return 0;
return 1;
}
int main(){
scanf("%lld",&n),l=1,r=1000000;
while(l<=r){
mid=l+r>>1;
if(mid*mid*mid>n)r=mid-1;
else l=mid+1;
}--l;
for(;l;--l)if(hui(l*l*l))return 0*printf("%lld",l*l*l);
}
20:24 才做出来,主要是第八行的 a[tot-i+1]
写成了 a[n-i+1]
,警钟长鸣。
20:24 D题
再次吐槽翻译软件。
看了十分钟题目才看出来,我是飞五。
这题用 STL 乱搞就行了。用数组维护每个人当前的得分,用 map
维护每个分数对应多少人,用 set
维护当前有多少种不同的得分。唯一的注意点是要开 long long
。
时间复杂度: O ( n log n ) O(n \log n) O(nlogn)
代码
#include <bits/stdc++.h>
using namespace std;
int n,t,x,y;
long long a[200001];
map<long long,int>mp;
set<long long>s;
int main(){
scanf("%d%d",&n,&t),mp[0]=n,s.insert(0);
for(int i=1;i<=t;++i){
scanf("%d%d",&x,&y);
if(!--mp[a[x]])s.erase(a[x]);
a[x]+=y,s.insert(a[x]),++mp[a[x]],printf("%d\n",s.size());
}return 0;
}
20:41 完成。
20:41 E题
切这题以前我看了一下榜,好家伙 E 过的人 怎么比 F 还少?再看了一眼题目,好像是暴力。死推结论失败了,只能去看看 F。
21:20 F题
首先,看翻译花了五分钟。。。
由于我实在太蒟蒻了,不会用线段树之类的高级数据结构,当时就心血来潮想用分块,可是时间原因,比完赛才打完操作一。所以赛后继续搞。
考虑 O ( n q ) O(nq) O(nq) 暴力怎么做:询问区间内维护最大值、次大值、最大值数量、次大值数量。
那我们分块的做法也类似,先预处理一开始每个块内的最大值等信息,然后该怎么做怎么做。
好在 22:58 的时候,WA 了三次终于 AC 了……
细节挺多的,直接上代码了吧。
时间复杂度: O ( q n + n ) O(q \sqrt n +n) O(qn+n)。这里为了方便,我直接令块长为 500 500 500,时间复杂度差不多。
代码
#include <cstdio>
using namespace std;
int a[401][501],zd[401],cd[401],zdcnt[401],cdcnt[401],n,q,tot,res,op,l,r,now,l1,l2,r1,r2,retzd,retcd,retzdcnt,retcdcnt;
int main(){
scanf("%d%d",&n,&q);for(int i=1;i<=n;++i)scanf("%d",&a[(i-1)/500+1][(i-1)%500+1]);
tot=(n-1)/500+1,res=(n-1)%500+1;
for(int i=1;i<tot;++i){
for(int j=1;j<501;++j){
if(a[i][j]>zd[i])cd[i]=zd[i],cdcnt[i]=zdcnt[i],zd[i]=a[i][j],zdcnt[i]=1;
else if(a[i][j]==zd[i])++zdcnt[i];
else if(a[i][j]>cd[i])cd[i]=a[i][j],cdcnt[i]=1;
else if(a[i][j]==cd[i])++cdcnt[i];
}
}
for(int j=1;j<=res;++j){
if(a[tot][j]>zd[tot])cd[tot]=zd[tot],cdcnt[tot]=zdcnt[tot],zd[tot]=a[tot][j],zdcnt[tot]=1;
else if(a[tot][j]==zd[tot])++zdcnt[tot];
else if(a[tot][j]>cd[tot])cd[tot]=a[tot][j],cdcnt[tot]=1;
else if(a[tot][j]==cd[tot])++cdcnt[tot];
}
while(q--){
scanf("%d%d%d",&op,&l,&r);
if(op==1){now=(l-1)/500+1,a[now][(l-1)%500+1]=r,zd[now]=cd[now]=zdcnt[now]=cdcnt[now]=0;
if(now==tot){
for(int j=1;j<=res;++j){
if(a[tot][j]>zd[tot])cd[tot]=zd[tot],cdcnt[tot]=zdcnt[tot],zd[tot]=a[tot][j],zdcnt[tot]=1;
else if(a[tot][j]==zd[tot])++zdcnt[tot];
else if(a[tot][j]>cd[tot])cd[tot]=a[tot][j],cdcnt[tot]=1;
else if(a[tot][j]==cd[tot])++cdcnt[tot];
}
}else{
for(int j=1;j<501;++j){
if(a[now][j]>zd[now])cd[now]=zd[now],cdcnt[now]=zdcnt[now],zd[now]=a[now][j],zdcnt[now]=1;
else if(a[now][j]==zd[now])++zdcnt[now];
else if(a[now][j]>cd[now])cd[now]=a[now][j],cdcnt[now]=1;
else if(a[now][j]==cd[now])++cdcnt[now];
}
}
}
if(op==2){l1=(l-1)/500+1,l2=(l-1)%500+1,r1=(r-1)/500+1,r2=(r-1)%500+1,retzd=retcd=retzdcnt=retcdcnt=0;
if(l1==r1){
for(int i=l2;i<=r2;++i){
if(a[l1][i]>retzd)retcd=retzd,retcdcnt=retzdcnt,retzd=a[l1][i],retzdcnt=1;
else if(a[l1][i]==retzd)++retzdcnt;
else if(a[l1][i]>retcd)retcd=a[l1][i],retcdcnt=1;
else if(a[l1][i]==retcd)++retcdcnt;
}
}else{
for(int i=l2;i<501;++i){
if(a[l1][i]>retzd)retcd=retzd,retcdcnt=retzdcnt,retzd=a[l1][i],retzdcnt=1;
else if(a[l1][i]==retzd)++retzdcnt;
else if(a[l1][i]>retcd)retcd=a[l1][i],retcdcnt=1;
else if(a[l1][i]==retcd)++retcdcnt;
}for(int i=l1+1;i<r1;++i){
if(zd[i]>retzd)retcd=retzd,retcdcnt=retzdcnt,retzd=zd[i],retzdcnt=zdcnt[i];
else if(zd[i]==retzd)retzdcnt+=zdcnt[i];
else if(zd[i]>retcd)retcd=zd[i],retcdcnt=zdcnt[i];
else if(zd[i]==retcd)retcdcnt+=zdcnt[i];
if(cd[i]>retcd)retcd=cd[i],retcdcnt=cdcnt[i];
else if(cd[i]==retcd)retcdcnt+=cdcnt[i];
}
for(int i=1;i<=r2;++i){
if(a[r1][i]>retzd)retcd=retzd,retcdcnt=retzdcnt,retzd=a[r1][i],retzdcnt=1;
else if(a[r1][i]==retzd)++retzdcnt;
else if(a[r1][i]>retcd)retcd=a[r1][i],retcdcnt=1;
else if(a[r1][i]==retcd)++retcdcnt;
}
}printf("%d\n",retcdcnt);
}
}
return 0;
}
G题我就看了一眼,不会做,所以就先咕咕咕着吧……
orz AK dalao。