2024暑假集训测试2

news/2024/11/17 7:37:50/文章来源:https://www.cnblogs.com/Charlieljk/p/18294756

前言

  • 比赛链接。

image

T1、T4 比较简单,打完基本就罚坐了,想了三个小时的 T2、T3 也没想出来。

T1 酸碱度中和

二分答案加贪心即可,先排序,每瓶可装 \(a_i\sim a_i+2*m\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{x=0;register bool z=true;register char c=getchar();for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);x=(z?x:~x+1);
}
void wt(int x){if(x>9)wt(x/10);putchar((x%10)+'0');}
void write(int x){if(x<0)putchar('-'),x=~x+1;wt(x);}
int n,m,l,r,mid,a[N],maxx,ans;
bool check(int x)
{int sum=0,now=a[1];for(int i=1;i<=n+1;i++)if(a[i]-now>2*x){now=a[i];sum++;if(sum>m) return 0;}return (sum<=m);
}
signed main()
{read(n),read(m);for(int i=1;i<=n;i++)read(a[i]),maxx=max(maxx,a[i]);sort(a+1,a+1+n);a[n+1]=0x7f7f7f7f;l=0,r=maxx;while(l<=r){mid=(l+r)>>1;if(check(mid)) r=mid-1,ans=mid;else l=mid+1;}write(ans);
}

T2 聪明的小明

  • 部分分 \(5pts\)\(k=m\) 时答案为 \(k!\)

  • 部分分 \(25pts\)\(n\le 20\& k=2\) 时爆搜。

  • 部分分 \(45pts\)\(k=2\) 时状压,如何状压在正解里说。

  • 正解:

    鉴于 \(m\le 10\) 且内存给了 \(1G\),考虑状压。

    状压的思路比较巧妙,对于长度为 \(m\)\(01\) 串,\(1\) 表示某数在这 \(m\) 位中最后一次出现在此处,\(0\) 则表示该数在后面还出现过,如 011 可以表示为 112、221、121、212 等。

    之所以要这么状压是因为需要处理第 \(m+1\) 位和第 \(1\) 位之间的影响。

    对于每一个状态,若 \(1\) 的个数恰好 \(=k\) 且最后一位为 \(1\) 时为合法状态。

    继续考虑每一种状态对应多少种情况,从后向前遍历,记录已经遍历到的 \(1\) 的个数,若遇到一个 \(1\),答案 \(\times (k-num)\),然后 \(sum+1\),若为 \(0\)\(\times num\),正确性显然。

    继续考虑如何转移,有 \(f_{i,s}=\sum f_{i-1,s'}\),其中 \(s\) 可以从 \(s'\) 转移过来。

    继续考虑一种状态 \(s\) 可以转化成什么状态,若 \(s\) 的第一位为 \(1\),说明该数仅出现过一次,则 \(m+1\) 位也必须为该数,如 101 尽可以转化为 011

    对于其余情况的状态,每一个 \(1\) 都可以移到 \(m+1\) 位,此位变为 \(0\),如 011 可以转化位 011101

    复杂度为 \(O(n2^m)\),若提前处理出所有合法状态的话可将复杂度优化到 \(O(nC_m^k)\)\(m=10,k=5\) 时取到最大为 \(O(252n)\)

    点击查看代码
    #include<bits/stdc++.h>
    #define int long long
    #define endl '\n'
    #define sort stable_sort
    using namespace std;
    const int N=1e5+2,P=998244353;
    template<typename Tp> inline void read(Tp&x)
    {x=0;register bool z=true;register char c=getchar();for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);x=(z?x:~x+1);
    }
    void wt(int x){if(x>9)wt(x/10);putchar((x%10)+'0');}
    void write(int x){if(x<0)putchar('-'),x=~x+1;wt(x);}
    int n,k,m,f[N][1025],c[1025],ans;
    int check(int sta)
    {if(c[sta]!=-1) return c[sta];if((sta&1)==0) return c[sta]=0;int sum=0,ans=1,now=sta;for(int i=1;i<=m;i++){if(sta&1)(ans*=(k-sum))%=P,sum++;else (ans*=sum)%=P;sta>>=1;}return c[now]=(sum==k)*ans;
    }
    void solve(int i,int sta)
    {if(check(sta)==0) return ;if((sta>>(m-1))&1) {int now=sta;sta^=(1<<(m-1));sta<<=1;sta|=1;(f[i+1][sta]+=f[i][now])%=P;return ;}for(int j=1;j<=m;j++)if((sta>>(j-1))&1){int now=sta;sta^=(1<<(j-1));sta<<=1;sta|=1;(f[i+1][sta]+=f[i][now])%=P;sta=now;}
    }
    signed main()
    {memset(c,-1,sizeof(c));read(n),read(k),read(m);for(int s=1;s<=(1<<m)-1;s+=2) f[m][s]=check(s);for(int i=m;i<=n-1;i++)for(int s=1;s<=(1<<m)-1;s+=2)solve(i,s);for(int s=1;s<=(1<<m)-1;s+=2)(ans+=f[n][s])%=P;write(ans);
    }
    

T3 线段树

定义 \(f_{l,r}\) 为区间 \(l\sim r\) 的贡献,有 \(f_{l,r}\) 下界为 \(1\)

对于线段树上一个区间 \([L,R]\),若存在一个询问区间 \([l,r]\)\([L,R]\) 存在交集且 \([L,R]\) 不被 \([l,r]\) 包含,说明 \([l,r]\) 被分成了至少两个区间,由此 \(f_{L,R}\) 的贡献 \(+1\)

由此我们处理出每个断点 \(i\) 被多少个询问区间包含,记为 \(w_i\),以及每个线段树上的区间 \([l,r]\) 被多少个询问区间包含,记为 \(sum_{l,r}\)

其中 \(w_i\) 可以在输入的时候直接差分处理,\(sum_{l,r}\) 可以类似于二维前缀和和区间 \(DP\) 维护,有:

\[sum_{l,r}=sum_{l-1,r}+sum_{l,r+1}-sum_{l-1,r+1}+num_{l,r} \]

\(num_{l,r}\) 表示询问中恰好区间 \([l,r]\) 的个数。

最后考虑 \(DP\) 转移,\(f_{l,r}\) 为线段数上区间 \([l,r]\) 最少能提供多少除 \(m\) 个基本询问外额外的贡献,有:

\[f_{l,r}=\min\limits_{k=l}^{r-1}\{f_{l,k}+f_{k+1,r}+w_k-sum_{l,r}\} \]

初始值 \(f_{i,i}\)\(0\),其余均赋成极大值,这与之前的 \(f_{l,r}\) 下界为 \(1\) 是矛盾的,但是鉴于对 \(f_{l,r}\) 的定义为额外贡献,其初始值应该为 \(0\),最后答案为 \(+m\) 即可。

最后答案为 \(f_{1,n}+m\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=510;
template<typename Tp> inline void read(Tp&x)
{x=0;register bool z=true;register char c=getchar();for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);x=(z?x:~x+1);
}
void wt(int x){if(x>9)wt(x/10);putchar((x%10)+'0');}
void write(int x){if(x<0)putchar('-'),x=~x+1;wt(x);}
int n,m,w[N],sum[N][N],f[N][N];
signed main()
{read(n),read(m);for(int i=1,l,r;i<=m;i++)read(l),read(r),    w[l]++,w[r]--,sum[l][r]++;for(int i=1;i<=n;i++) w[i]+=w[i-1];for(int i=n;i>=1;i--)for(int l=1;l+i-1<=n;l++){int r=l+i-1;sum[l][r]=sum[l][r]+sum[l-1][r]+sum[l][r+1]-sum[l-1][r+1];}memset(f,0x3f,sizeof(f));for(int i=1;i<=n;i++) f[i][i]=0;for(int i=2;i<=n;i++)for(int l=1;l+i-1<=n;l++){int r=l+i-1;for(int k=l;k<r;k++)f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+w[k]-sum[l][r]);}write(f[1][n]+m);
}

T4 公路

贪心加模拟即可。

当前对于到达了车站 \(i\),继续向前找到一个 \(j\)\(j\) 分为两种情况:

  1. 在油箱允许的范围内找到的第一个油价小于 \(i\) 的,此时只需讲油加到足够支撑到车站 \(j\) 的即可。
  2. 在油箱允许的范围内没有找到任何一个油价小于 \(i\) 的,则在该范围内找到油价最小的一个车站 \(j\),此时直接将油箱加满,防止在更贵的地方买更多的油。

处理过后直接另 \(i=j\) 即可,同时维护一个变量保存油箱内还剩下多少油。

鉴于双指针做法,随机数据下复杂度近似于 \(O(n)\),油价单调递减数据下为严格 \(O(n)\),油价单调递增且 \(c\ge\sum\limits_{i=0}^{n-1}v_i\) 数据下复杂度退化为 \(O(n^2)\),在数据比较水的情况下可以通过此题。

利用单调队列优化可将复杂度优化为严格线性,懒得打了但是。

点击查看暴力代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{x=0;register bool z=true;register char c=getchar();for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);x=(z?x:~x+1);
}
void wt(int x){if(x>9)wt(x/10);putchar((x%10)+'0');}
void write(int x){if(x<0)putchar('-'),x=~x+1;wt(x);}
int n,m,d[N],a[N],f[N],ans,now;
signed main()
{read(n),read(m);for(int i=1,v;i<=n;i++)read(v),d[i]=d[i-1]+v;for(int i=0;i<=n-1;i++) read(a[i]);int j;for(int i=0;i<=n-1;i=j){j=i+1;int k,minn=0x7f7f7f7f;while(j<=n){if(d[j]-d[i]>m) {j--; break;}if(a[j]<a[i]) break;if(a[j]<minn) minn=a[j],k=j;j++;}if(a[j]<a[i])ans+=(d[j]-d[i]-now)*a[i],now=0;else {j=k;ans+=(m-now)*a[i];now=m-d[j]+d[i];}}write(ans);
}
粘一个官方题解的单调队列优化代码
#include<bits/stdc++.h>
#define ll long long
#define maxn 1000005
#define mod 1000000007
using namespace std;
ll n,C;
ll x[maxn],p[maxn];
pair<ll,ll> Q[maxn+maxn]; 
int head,tail;
int main()
{cin>>n>>C;for (int i=1;i<=n;i++) cin>>x[i];for (int i=1;i<=n;i++) cin>>p[i];head=1; tail=1;Q[head]={1ll<<30,C}; //为了保证队列里总大小是Cll sum=0;for (int i=1;i<=n;i++){ll tt=0;//删掉末尾不如p[i]的决策while (head<=tail && Q[tail].first>=p[i]) {tt+=Q[tail].second; tail--;}Q[++tail]={p[i],tt};//在队列的开头拿出x[i]的油来加ll ret=x[i];while (ret){ll num=min(ret,Q[head].second);sum+=Q[head].first*num; Q[head].second-=num; ret-=num;if (Q[head].second==0) head++;}Q[++tail]={1ll<<30,x[i]}; //为了保证队列里总大小是C}cout<<sum<<endl;
}

总结

要学会面向数据范围,确定正确的思路,如 T2 想出状压。

好好复习一下区间 DP。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/741883.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HAJX[2024] 15Day游记

洛谷食用 博客食用 简介:这是一个正在学习C++的OIer(很蒻很蒻)的日常记录。 (注:2024.7.5-7.20集训日更) 放在前面: 本贴只是记录一下本蒟蒻的生活,(太菜了),佬们轻喷谢谢~浏览次数:(由于网站原因可能无法显示,属于正常现象)Day 0 期待集训ing 。0-上午 在来的路上…

闲话 24.7.10

另类的……杨图!闲话 啊,zzz 真好玩啊! 慢热型,战斗非重点,美术风格超赞。如果不排斥米家 f2p 游戏,推荐大家玩一玩。 我是冲着妹妹去的 未来会补一些杨表公式的证明。现在先咕! 推歌:辰砂 by Licis et al. feat 洛天依AI 增补:另类杨图对应杨表计数 前置知识:杨表 什…

量化交易入门:如何在QMT中配置Python环境,安装第三方依赖包

哈喽,大家好,我是木头左!引言 QMT,作为量化交易系统中的佼佼者,以其强大的功能和灵活的操作性,受到了广大投资者的青睐。但是,对于很多新手来说,如何在QMT中配置Python环境,安装第三方依赖包,却是一个让人头疼的问题。本文将从零开始,手把手教你如何在QMT中配置Pyth…

uniapp-Java使用AES加密解密

操作前 uniapp 需要安装 npm install crypto-js 在需要使用的界面加入 import CryptoJS from crypto-js java端<!-- spring security 安全认证 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-s…

python项目导入上级目录设置”的setting.json是不是哪里还有错误呀?

大家好,我是Python进阶者。 一、前言 前几天在Python白银交流群【王者级混子】问了一个Python代码处理的问题,问题如下:大佬们,我想问问我抄网上“vscode运行python项目导入上级目录设置”的setting.json是不是哪里还有错误呀?还是没法导入上级目录二、实现过程 这里后来很…

伙伴活动|AI硬件大潮来袭,深圳的创客们在哪里?

「每一种硬件产品,都会被 GenAI 重新做一遍。」分享一个社区伙伴「未来光锥」参与主办的活动。如果你同时对 AI 和硬件感兴趣,提到 maker 一词仍然会激动。推荐你参与这次活动。AI 玩具Folotoy 的创始人、RTE 开发者社区成员王乐也将参与本次活动并分享。也推荐你收听王乐参与…

Cilium Socket LB 特性

Cilium Socket LB 特性Cilium Socket LB 一、环境信息主机 IPubuntu 172.16.94.141软件 版本docker 26.1.4helm v3.15.0-rc.2kind 0.18.0kubernetes 1.23.4ubuntu os Ubuntu 20.04.6 LTSkernel 5.11.5 内核升级文档二、Cilium SocketLB 模式认知 负载均衡的实现方式通常有如下两…

高考后第一次Codeforces Round 952 (Div. 4)

A Creating Words 思路:拿一个容器交换两数值即可 #include<bits/stdc++.h> using namespace std; const int N = 100001; char a[N],b[N]; int main() {int n;scanf("%d",&n);while(n--){scanf("%s %s",a,b);char jiaohuan = a[0];a[0] = b[0]…

前端如何取消接口调用

🧑‍💻 写在开头 点赞 + 收藏 === 学会🤣🤣🤣 1. xmlHttpRequest是如何取消请求的?实例化的XMLHttpRequest对象上也有abort方法const xhr = new XMLHttpRequest(); xhr.addEventListener(load, function(e) {console.log(this.responseText); }); xhr.open(GET, htt…

篮球比赛电子计分牌

在学习单片机课设“篮球比赛电子计分牌”的时候遇到了很多问题。在网上搜索到的资源很杂很乱,很多内容都需要付费,在学习的过程遇到了不少的阻力,因此我打算把我所做的拿出来与大家共同讨论,不足的地方还请多多指教哈。学艺不精,成绩仅为良好,大家参考就行。另外能激发后…

学习SpringCloud环境搭配

今天准备学习一下springcloud,在网上找了一个最新的学习视频需要更新一下之前安装的软件版本。突然想起来我还有个博客园的账号,就想记录一下环境搭建。 主要是分为以下几个部分Java 17+ Maven 3.9+ Mysql 8.0+ cloud 2023.0.0 boot 3.2.0 cloud alibaba 2022.0.0.0 之前…

进度报告4

(1)代码案例练习 1.public class helloworld { public static void main(String[] args) { double Price;int month;String x; Price=price(1000,6,"头等舱") ; System.out.println("优惠价为:"+Price); } public static double price(double a,int b,St…