九下三月下旬日记
3.21
- 代班主任在 3.14 只说了周五换课,没有说周四换课的事情。 @wkh2008 , @xrlong 和 @wang54321 以为周四也换课,就在班里等着,等物理教练进屋讲课了要把他们赶走,才意识到没换课。到机房后 \(miaomiao\) 和 \(huge\) 说既然这一节课其他科上奥赛了,那咱也上奥赛。
- 实际是周四也换课了,但由于收拾教室占了节奥赛自习,所以把早上的公自改成奥赛自习了。
- 吃晚饭的路上,看见年级德育主任在和我们体育老师不知道在说什么。
- 晚上考二调,但是今天奥赛正常,除了下午第 \(10\) 节课必须回班上公自加收拾教室。
- 回教室拿书的时候看见 \(field\) 了,和 \(field\) 闲聊了几句,然后又看见了年级主任和校长来 \(5\) 楼,路过厕所的时候看见有其他学校的人也来和我们一起考试。
- 晚上第一科是语文,考到 \(20:40\) 回班上公自。
- 语文第一题理解性默写第一个就想不起来;第二题让找错别字,没敢写“谛听”;头一次见诗歌阅读考诗歌作者的,一开始没想起来,后悔没仔细看《长安三万里》了。
闲话
做题纪要
CF1628D2 Game on Sum (Hard Version)
CF494C Helping People
2024年中国传媒大学程序设计大赛(同步赛)E 小红的矩阵构造(二)
-
从左向右复制 \(2 \times 2\) 的矩阵即可。
点击查看代码
int a[1010][1010]; int main() { int n,m,k,i,j; cin>>n>>m>>k; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(i+1<=n&&j+1<=m) { a[i][j]=a[i+1][j]=a[i][j+1]=a[i+1][j+1]=1; k--; if(k==0) { break; } } } if(k==0) { break; } } if(k==0) { for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { cout<<a[i][j]; } cout<<endl; } } else { cout<<"-1"<<endl; } return 0; }
2024年中国传媒大学程序设计大赛(同步赛)H 小红的生物实验
-
\(DFS\) 板子,记得处理边界情况。
点击查看代码
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}},vis[1010][1010]; char c[1010][1010]; void dfs(int x,int y,int n,int m) { vis[x][y]=1; if(c[x][y]=='*') { c[x][y]='.'; return; } else { for(int i=0;i<=3;i++) { if(0<=x+dir[i][0]&&x+dir[i][0]<=n+1&&0<=y+dir[i][1]&&y+dir[i][1]<=m+1&&vis[x+dir[i][0]][y+dir[i][1]]==0) { dfs(x+dir[i][0],y+dir[i][1],n,m); } } } } int main() { int n,m,i,j; cin>>n>>m; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { cin>>c[i][j]; } } dfs(0,0,n,m); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { cout<<c[i][j]; } cout<<endl; } return 0; }
3.22
闲话
- 上午数学,历史,考完回班上英语自习。
- 数学写田忌和齐王博弈,但没说清楚田忌和齐王是否按照最优策略。
- 下午英语,化学,考完回班上政治自习,现班主任顺便说了下晚三换座的事情。
- 英语听短文填空不会写
prepare
,单词拼写不会写snack
,作文不知道写啥,纯纯罚坐。
- 英语听短文填空不会写
- 晚三政治,物理。考完已经 \(21:30\) 了,匆忙回班换了个座,只把书搬进来了,没有细收拾。
做题纪要
3.23
闲话
- 早读的时候,现班主任狂 \(D\) 了我们一下,说我们的状态远不如刚分班的那一周,年级那边也对奥赛班有点不满。
- 上午因某个物理老师录公开课需要,在没有告知现班主任,年级德育主任的情况下,叫了班里的 \(20\) 多个人去试听,因此旷掉了课间操和政治讲评。我们去跑课间操的时候,被年级德育主任 \(D\) 了。下午因正式录课,旷掉了历史讲评,此时班里只有 \(10\) 多个人,历史老师和现班主任说了这件事之后,现班主任 \(D\) 了我们一下,说让我们以后别再掺和这些事情,心气别太飘。
- 轻易地相信别人还是太单纯了,即使是老师。毕竟最近 hs 【数据删除】 闹得沸沸扬扬的。
- 二调成果:语文 \(94\) ,数学 \(109\) ,英语 \(101\) ,政治 \(94\) ,历史 \(87\) ,物理 \(89\) ,化学 \(92\) ,原班级第 \(18\) ,现班级估计得倒数了,年级 \(455\) 名,和 @wkh2008 一个分数,下次真成一个考场的了。
- 下午高一,初三,高三的放假了。放假的时候,操场上各个班才来了 \(5,6\) 个人的时候,年级德育主任就让直接走了,没再站队等人齐了一起走。
做题纪要
3.24
闲话
- 下午返校后直接去机房了,因没和教练或现班主任说,被现班主任 \(D\) 了。
做题纪要
luogu P6323 [COCI2006-2007#4] ZBRKA
-
多倍经验: luogu P2513 [HAOI2009] 逆序对数列 | luogu P1521 求逆序对 | SP64 PERMUT1 - Permutations
-
设 \(f_{i,j}\) 表示 \(1 \sim i\) 的全排列中存在 \(j\) 个逆序对的方案数,状态转移方程为 \(f_{i,j}=\sum\limits_{k=j-\min(i-1,j)}^{j}f_{i-1,k}=\sum\limits_{k=0}^{j}f_{i-1,k}-\sum\limits_{k=0}^{j-\min(i-1,j)-1}f_{i-1,k}\) 。
-
需要滚动数组和前缀和优化。
点击查看代码
const ll p=1000000007; ll f[10010],g[2][10010]; int main() { ll n,m,i,j,k; cin>>n>>m; f[0]=1; for(i=0;i<=m;i++) { g[1][i]=(((i==0)?0:g[1][i-1])+f[i])%p; } for(i=2;i<=n;i++) { for(j=0;j<=m;j++) { f[j]=(g[(i-1)&1][j]-((j-min(i-1,j)-1<0)?0ll:g[(i-1)&1][j-min(i-1,j)-1])+p)%p; g[i&1][j]=(((j==0)?0:g[i&1][j-1])+f[j])%p; } } cout<<f[m]<<endl; return 0; }
3.25
闲话
- 学校搞了个消防演练(下午起床后)和地震演练(下午大课间)。下午大课间因在机房, \(miaomiao\) 没让下去。
- 下午 \(13:55 \sim 18:05\) 安排了一场模拟赛。
- 题解: 初三奥赛模拟测试3 。
做题纪要
LibreOJ 6282. 数列分块入门 6
-
对于每个块内可以使用
vector
来维护插入。 -
当一个块内元素数量过多时,重新进行分块求解。
点击查看代码
ll a[200010],L[200010],R[200010],pos[200010],klen,ksum,maxklen,m; vector<ll>b[500]; void init(ll n,ll pd) { if(pd==1) { n=0; for(ll i=1;i<=ksum;i++) { for(ll j=0;j<b[i].size();j++) { n++; a[n]=b[i][j]; } b[i].clear(); } } klen=sqrt(n); ksum=n/klen; maxklen=sqrt(klen)*klen; for(ll i=1;i<=ksum;i++) { L[i]=R[i-1]+1; R[i]=R[i-1]+klen; } if(R[ksum]<n) { ksum++; L[ksum]=R[ksum-1]+1; R[ksum]=n; } for(ll i=1;i<=ksum;i++) { for(ll j=L[i];j<=R[i];j++) { pos[j]=i; b[i].push_back(a[j]); } } } pair<ll,ll> query(ll l) { ll i; for(i=1;i<=ksum&&l-1>=b[i].size();i++) { l-=b[i].size(); } return make_pair(i,l-1); } void update(ll l,ll val) { m++; pair<ll,ll>x=query(l); b[x.first].insert(b[x.first].begin()+x.second,val); if(b[x.first].size()>maxklen) { init(m,1ll); } } int main() { ll n,pd,l,r,val,i; scanf("%lld",&n); m=n; for(i=1;i<=n;i++) { scanf("%lld",&a[i]); } init(n,0ll); for(i=1;i<=n;i++) { scanf("%lld%lld%lld%lld",&pd,&l,&r,&val); if(pd==0) { update(l,r); } else { printf("%lld\n",b[query(r).first][query(r).second]); } } return 0; }
LibreOJ 6284. 数列分块入门 8
-
由于每次询问后都有一次修改操作,猜测经过一定数量的操作后数列的权值不同的区间会越来越少。
-
记录整块内元素权值是否都相等,然后对于权值相等的整块直接 \(O(1)\) 统计答案,否则暴力进行查询。
-
时间复杂度分析详见 「分块」数列分块入门1 – 9 by hzwer 分块入门 8 by hzwer 。
点击查看代码
ll a[100010],L[100010],R[100010],pos[100010],vis[100010],f[100010],klen,ksum; void init(ll n) { klen=sqrt(n); ksum=n/klen; for(ll i=1;i<=ksum;i++) { L[i]=R[i-1]+1; R[i]=R[i-1]+klen; } if(R[ksum]<n) { ksum++; L[ksum]=R[ksum-1]+1; R[ksum]=n; } for(ll i=1;i<=ksum;i++) { for(ll j=L[i];j<=R[i];j++) { pos[j]=i; } } } void update(ll l,ll r,ll val) { if(pos[l]==pos[r]) { if(vis[pos[l]]==1) { for(ll i=L[pos[l]];i<=R[pos[l]];i++) { a[i]=f[pos[l]]; } vis[pos[l]]=0; } for(ll i=l;i<=r;i++) { a[i]=val; } } else { if(vis[pos[l]]==1) { for(ll i=L[pos[l]];i<=R[pos[l]];i++) { a[i]=f[pos[l]]; } vis[pos[l]]=0; } for(ll i=l;i<=R[pos[l]];i++) { a[i]=val; } for(ll i=pos[l]+1;i<=pos[r]-1;i++) { vis[i]=1; f[i]=val; } if(vis[pos[r]]==1) { for(ll i=L[pos[r]];i<=R[pos[r]];i++) { a[i]=f[pos[r]]; } vis[pos[r]]=0; } for(ll i=L[pos[r]];i<=r;i++) { a[i]=val; } } } ll query(ll l,ll r,ll val) { ll ans=0; if(pos[l]==pos[r]) { if(vis[pos[l]]==1) { for(ll i=L[pos[l]];i<=R[pos[l]];i++) { a[i]=f[pos[l]]; } vis[pos[l]]=0; } for(ll i=l;i<=r;i++) { ans+=(a[i]==val); } } else { if(vis[pos[l]]==1) { for(ll i=L[pos[l]];i<=R[pos[l]];i++) { a[i]=f[pos[l]]; } vis[pos[l]]=0; } for(ll i=l;i<=R[pos[l]];i++) { ans+=(a[i]==val); } for(ll i=pos[l]+1;i<=pos[r]-1;i++) { if(vis[i]==0) { for(ll j=L[i];j<=R[i];j++) { ans+=(a[j]==val); } } else { ans+=(f[i]==val)*klen; } } if(vis[pos[r]]==1) { for(ll i=L[pos[r]];i<=R[pos[r]];i++) { a[i]=f[pos[r]]; } vis[pos[r]]=0; } for(ll i=L[pos[r]];i<=r;i++) { ans+=(a[i]==val); } } return ans; } int main() { ll n,l,r,val,i; scanf("%lld",&n); for(i=1;i<=n;i++) { scanf("%lld",&a[i]); } init(n); for(i=1;i<=n;i++) { scanf("%lld%lld%lld",&l,&r,&val); printf("%lld\n",query(l,r,val)); update(l,r,val); } return 0; }
3.26
闲话
- \(miaomiao\) 因昨天 \(11\) 个人中仅有 \(8\) 个人打模拟赛, \(D\) 了我们一下。
做题纪要
LibreOJ 6285. 数列分块入门 9
-
多倍经验: luogu P4168 [Violet]蒲公英
-
将 \([l,r]\) 分成 \([l,L),[L,R],(R,r]\) 三部分,由于区间众数不满足区间可加性,即 \([l,r]\) 的众数只可能来自 \([L,R]\) 的众数和出现在 \([l,R),(R,r]\) 之间的数。
-
由于 \(a_{i}\) 极大,但 \(n\) 较小,需要事先将 \(a_{i}\) 进行离散化。
-
对于每个数值建立一个
vector
,按顺序保存该数值在序列 \(a\) 中每次出现的位置。 -
对于散块,暴力查询其中的每个数 \(x\) ,二分出 \(x\) 在 \([l,r]\) 中出现的次数;对于整块,预处理出 \(f_{i,j}\) 表示第 \(i\) 块到第 \(j\) 块的众数进行查询。
-
块长取 \(\sqrt{\frac{n}{\log_{2}{n}}}\) 。
点击查看代码
ll a[100010],b[100010],c[100010],d[100010],L[100010],R[100010],pos[100010],cnt[100010],f[1300][1300],klen,ksum; vector<ll>val[100010]; void init(ll n) { ll num,ans; klen=sqrt(n/log2(n)); ksum=n/klen; for(ll i=1;i<=ksum;i++) { L[i]=R[i-1]+1; R[i]=R[i-1]+klen; } if(R[ksum]<n) { ksum++; L[ksum]=R[ksum-1]+1; R[ksum]=n; } for(ll i=1;i<=ksum;i++) { for(ll j=L[i];j<=R[i];j++) { pos[j]=i; } } for(ll i=1;i<=ksum;i++) { num=ans=0; memset(cnt,0,sizeof(cnt)); for(ll j=L[i];j<=n;j++) { cnt[c[j]]++; if(cnt[c[j]]>num||(cnt[c[j]]==num&&d[ans]>d[c[j]])) { ans=c[j]; num=cnt[c[j]]; } f[i][pos[j]]=ans; } } } ll query(ll l,ll r) { ll ans,num,sum; if(pos[l]==pos[r]) { ans=num=0; for(ll i=l;i<=r;i++) { sum=upper_bound(val[c[i]].begin(),val[c[i]].end(),r)-lower_bound(val[c[i]].begin(),val[c[i]].end(),l); if(sum>num||(sum==num&&d[ans]>d[c[i]])) { ans=c[i]; num=sum; } } } else { ans=f[pos[l]+1][pos[r]-1]; num=upper_bound(val[ans].begin(),val[ans].end(),r)-lower_bound(val[ans].begin(),val[ans].end(),l); for(ll i=l;i<=R[pos[l]];i++) { sum=upper_bound(val[c[i]].begin(),val[c[i]].end(),r)-lower_bound(val[c[i]].begin(),val[c[i]].end(),l); if(sum>num||(sum==num&&d[ans]>d[c[i]])) { ans=c[i]; num=sum; } } for(ll i=L[pos[r]];i<=r;i++) { sum=upper_bound(val[c[i]].begin(),val[c[i]].end(),r)-lower_bound(val[c[i]].begin(),val[c[i]].end(),l); if(sum>num||(sum==num&&d[ans]>d[c[i]])) { ans=c[i]; num=sum; } } } return ans; } int main() { ll n,l,r,i; scanf("%lld",&n); for(i=1;i<=n;i++) { scanf("%lld",&b[i]); a[i]=b[i]; } sort(b+1,b+1+n); b[0]=unique(b+1,b+1+n)-(b+1); for(i=1;i<=n;i++) { c[i]=lower_bound(b+1,b+1+b[0],a[i])-b; d[c[i]]=a[i]; val[c[i]].push_back(i); } init(n); for(i=1;i<=n;i++) { scanf("%lld%lld",&l,&r); printf("%lld\n",d[query(l,r)]); } return 0; }
tgHZOJ 2194.序列问题
- 详见 初三奥赛模拟测试3 T2 序列问题 。
tgHZOJ 2193.网格图
- 详见 初三奥赛模拟测试3 T1 网格图 。
3.27
闲话
- 因二调年级排名退步太多和历史没上 \(90\) 被年级德育主任 \(D\) 了。
- \(miaomiao\) 本来说今天讨论动态规划专题的题的,但没组织讨论。
做题纪要
AT_arc090_b [ABC087D] People on a Line
LibreOJ 10088. 「一本通 3.4 例 2」出纳员问题
AT_abc328_f [ABC328F] Good Set Query
-
带权并查集维护即可。
点击查看代码
ll f[200010],l[200010]; ll find(ll x) { if(f[x]==x) { return x; } else { ll y=find(f[x]); l[x]+=l[f[x]]; f[x]=y; return f[x]; } } int main() { ll n,m,a,b,d,x,y,i; cin>>n>>m; for(i=1;i<=n+1;i++) { f[i]=i; } for(i=1;i<=m;i++) { cin>>a>>b>>d; x=find(a); y=find(b); if(x==y) { if(l[b]-l[a]==d) { cout<<i<<" "; } } else { f[y]=x; l[y]=l[a]+d-l[b]; cout<<i<<" "; } } return 0; }
3.28
闲话
- 现班主任称 3.14 换课的时候他没同意,“我一没签字,二没画押,我咋知道你们当时怎么换的课”,所以周四、周五的换课取消了。
- \(miaomiao\) 催了下赶紧做动态规划专题的题。
- 晚上做了胸透的体检。
做题纪要
luogu P3203 [HNOI2010]弹飞绵羊
-
预处理出 \(to_{i}\) 表示 \(i\) 跳出 \(i\) 所在块后所在的位置, \(sum_{i}\) 表示 \(i\) 跳出 \(i\) 所在块的次数,状态转移方程为 \(to_{i}= \begin{cases} i+a_{i} & i+a_{i}>R_{i} \\ to_{i+a_{i}} & i+a_{i} \le R_{i} \end{cases}\) , \(sum_{i}= \begin{cases} 1 & i+a_{i}>R_{i} \\ sum_{i+a_{i}}+1 & i+a_{i} \le R_{i} \end{cases}\) 。
-
块长取 \(\sqrt{n}\) 。
点击查看代码
int a[200010],L[200010],R[200010],pos[200010],sum[200010],to[200010],klen,ksum; void init(int n) { klen=sqrt(n); ksum=n/klen; for(int i=1;i<=ksum;i++) { L[i]=R[i-1]+1; R[i]=R[i-1]+klen; } if(R[ksum]<n) { ksum++; L[ksum]=R[ksum-1]+1; R[ksum]=n; } for(int i=1;i<=ksum;i++) { for(int j=L[i];j<=R[i];j++) { pos[j]=i; } } for(int i=ksum;i>=1;i--) { for(int j=R[i];j>=L[i];j--) { to[j]=(j+a[j]>R[i])?j+a[j]:to[j+a[j]]; sum[j]=(j+a[j]>R[i])?1:sum[j+a[j]]+1; } } } void update(int l,int val) { a[l]=val; for(int i=R[pos[l]];i>=L[pos[l]];i--) { to[i]=(i+a[i]>R[pos[l]])?i+a[i]:to[i+a[i]]; sum[i]=(i+a[i]>R[pos[l]])?1:sum[i+a[i]]+1; } } int query(int l,int r) { int ans=0; for(int i=l;i<=r;i=to[i]) { ans+=sum[i]; } return ans; } int main() { int n,m,pd,l,val,i; cin>>n; for(i=1;i<=n;i++) { cin>>a[i]; } init(n); cin>>m; for(i=1;i<=m;i++) { cin>>pd>>l; l++; if(pd==1) { cout<<query(l,n)<<endl; } else { cin>>val; update(l,val); } } return 0; }
CF1392H ZS Shuffles Cards
luogu P2607 [ZJOI2008] 骑士
luogu P1453 城市环路
3.29
闲话
- 起床后遇见 @iCostalymh 了,和他闲聊了几句。
- 下午做了血压和心电图的体检,占了一节多课的时间。
做题纪要
Acwing 289. 环路运输
-
在仓库 \(1\) 和 \(n\) 之间把环断开,然后复制一倍接在末尾,形成长度为 \(2n\) 的直线公路,即有 \(a_{i}=a_{i+n} (1 \le i \le n)\) 。
-
对于原来环形公路上的任意两座仓库 \(i,j(1 \le j<i \le n)\) ,代价为 \(\begin{cases} a_{i}+a_{j}+i-j & i-j \le \frac{n}{2} \\ a_{j+n}+a_{i}+j+n-i & i-j> \frac{n}{2} \end{cases}\) 。即对于直线公路上的任意两座仓库 \(i,j(1 \le j<i \le 2n,i-j \le \frac{n}{2})\) ,代价为 \(a_{i}+a_{j}+i-j\) 。
-
单调队列维护递增的 \(a_{i}-i\) 即可。
点击查看代码
int a[2000010]; deque<int>q; int main() { int n,ans=0,i; cin>>n; for(i=1;i<=n;i++) { cin>>a[i]; a[i+n]=a[i]; } for(i=1;i<=2*n;i++) { while(q.empty()==0&&q.front()<i-n/2) { q.pop_front(); } if(q.empty()==0) { ans=max(ans,a[i]+i+a[q.front()]-q.front()); } while(q.empty()==0&&a[q.back()]-q.back()<=a[i]-i) { q.pop_back(); } q.push_back(i); } cout<<ans<<endl; return 0; }
luogu P1543 [POI2004] SZP
luogu P5022 [NOIP2018 提高组] 旅行
3.30
闲话
- \(miaomiao\) 让 @xrlong 组织讲了 动态规划专题 的题。
- 下午做了脊柱侧弯的体检。
- 体活的时候,现班主任让回去开个小会,讲了讲周测的安排。回到机房后,发现 【数据删除】 【数据删除】 的事情被 【数据删除】 发现了, 【数据删除】 问 【数据删除】 【数据删除】 哪里来的,然后【数据删除】 就把 【数据删除】 供出去了。 @CuFeO4 问了 \(miaomiao\) 晚上能不能打 ABC ,\(miaomiao\) 没同意。
- 晚上 @CuFeO4 找现班主任请 ABC 的假,结果只请到了晚三的时间。
做题纪要
CF285E Positions in Permutations
CF536D Tavas in Kansas
3.31
闲话
- 白天英语周测,阅读比较抽象,根本读不懂,但对了答案后发现阅读全对了,离谱。
- 去吃早饭的路上,看见 @5k_sync_closer 和另外几个高一的在打羽毛球。
- 晚上开班会。现班主任分析成绩的时候 \(D\) 我就差报我身份证号了;讲了讲期中的重要性,“用11天的努力换长时间家长和老师的支持”; \(D\) 了 \(D\) 信奥,称中午吃完饭后的 \(20min\) 都利用不好,平常自习请假去机房效率怎么保证;展示了没有强基计划前学长的辉煌战绩,然后喂了点鸡汤。
做题纪要
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18086539,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。