USACO2025 JAN Platinum 简要题解

news/2025/2/3 18:34:13/文章来源:https://www.cnblogs.com/Nesraychan/p/18697609

A

直接区间 dp 即可。

#include<bits/stdc++.h>
#define IL inline
#define reg register
#define N 755
#define oo (1<<29)
IL int read()
{reg int x=0,f=0; reg char ch=getchar();while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return f?-x:x;
}int n,a[N][N],s[N][N],f[N][N];IL void cmin(reg int &x,reg int y){x>y?x=y:0;}main()
{n=read();for(reg int i=1,j;i<=n;++i)for(j=1;j<i;++j)a[j][i]=read();for(reg int l=1,r;l<=n;++l)for(r=l;r<=n;++r)if(a[l][r]<0)s[l][r]=-a[l][r];for(reg int l=1,r;l<=n;++l)for(r=l;r<=n;++r)s[l][r]+=s[l][r-1];for(reg int r=1,l;r<=n;++r)for(l=r;l;--l)s[l][r]+=s[l+1][r];for(reg int l=n,r,i,w;l;--l)for(r=l+1;r<=n;++r){f[l][r]=oo;for(i=r;i>l;--i){w=f[l][i-1]+f[i][r];if(i!=l+1)w+=s[l+1][r]-s[l+1][i-1]-s[i][r];if(a[l][i]>0)w+=a[l][i];cmin(f[l][r],w);}}printf("%d\n",f[1][n]);
}

B

首先注意到只会有一个不在头尾的操作,这可以用调整法说明,如果有两个就可以往外移。

然后考察只操作头尾的答案,二分答案,确定和之后是容易判断的。

而存在不在头尾操作时的答案最多只会小一,所以我们只需要一次 check。

这时合法首先要满足只用头尾的操作所有元素 \(<n\),我们可以根据此求出头部操作次数的范围。

接着所有 \(>0\) 的元素会对中间操作的位置提出限制,而每个点所有这样的时刻数之和是 \(O(n\log n)\) 的。

然后注意到每个限制是一个区间,所以对每个时刻判断所有区间是否并集为全集即可。

时间复杂度 \(O(n\log^2n)\),常数极小,最大点 \(<\text{100ms}\)

#include<bits/stdc++.h>
#define IL inline
#define reg register
#define N 100100
#define int long long
IL int read()
{reg int x=0,f=0; reg char ch=getchar();while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return f?-x:x;
}int n,a[N];IL void cmax(reg int &x,reg int y){x<y?x=y:0;}
IL void cmin(reg int &x,reg int y){x>y?x=y:0;}
IL int min(reg int x,reg int y){return x<y?x:y;}
IL int max(reg int x,reg int y){return x>y?x:y;}IL int ask(reg int x,reg int y)
{if(x<=0)return 0;return (x+y-1)/y;
}IL bool check1(reg int s) // s = x + y
{reg int x=0,y=0;for(reg int i=1,cx,cy;i<=n;++i){cx=i-1,cy=n-i;if(cx==cy){if(cx*s<a[i])return 0;continue;}if(cx<cy)cmax(y,ask(a[i]-cx*s,cy-cx));else cmax(x,ask(a[i]-cy*s,cx-cy));}return x+y<=s;
}IL int Abs(reg int x){return x<0?-x:x;}std::vector<int>vec[N*3];struct Range{int l,r;}p[N];
int m;IL bool check2(reg int s)
{static int b[N];for(reg int i=1;i<=n;++i)b[i]=a[i];reg int L=0,R=s;for(reg int i=1,cx,cy,l,r,k,c;i<=n;++i){cx=i-1,cy=n-i;if(cx==cy){if(cx*s+cx<a[i])return 0;continue;}if(cx>cy){k=a[i]-cy*s,c=cx-cy;l=ask(k-n,c),r=ask(k,c);cmax(L,l);}else{k=a[i]-cx*s,c=cy-cx;l=ask(k-n,c),r=ask(k,c);cmin(R,s-l);           }}if(L>R)return 0;if(R-L>=n*3)return 1;for(reg int i=0;i<=R-L;++i)vec[i].clear();for(reg int i=1,cx,cy,l,r,k,c,j;i<=n;++i){cx=i-1,cy=n-i;if(cx==cy){for(j=0;j<=R-L;++j)vec[j].push_back(i);}else if(cx>cy){k=a[i]-cy*s,c=cx-cy;l=ask(k-n,c),r=ask(k,c);for(j=l;j<r;++j)if(L<=j&&j<=R)vec[j-L].push_back(i);}else{k=a[i]-cx*s,c=cy-cx;l=ask(k-n,c),r=ask(k,c);for(j=l;j<r;++j)if(L<=s-j&&s-j<=R)vec[s-j-L].push_back(i);}}for(reg int x=L,y,k,i;x<=R;++x){y=s-x,m=0;for(auto i:vec[x-L]){k=a[i]-(i-1)*x-(n-i)*y;if(k>0)p[++m]={max(1,i-k+1),min(n,i+k-1)};}std::sort(p+1,p+1+m,[&](auto a,auto b){return a.l<b.l;});for(i=1,k=0;i<=m;++i){if(p[i].l>k+1)return 1;cmax(k,p[i].r);}if(k<n)return 1;}return 0;
}IL void work()
{n=read();for(reg int i=1;i<=n;++i)a[i]=read();reg int l=0,r=2e18,mid;r=r/(n-1)+5;while(l<=r){mid=l+r>>1;if(check1(mid))r=mid-1;else l=mid+1;}if(l<=1){printf("%lld\n",l);return;}if(check2(l-2))printf("%lld\n",l-1);else printf("%lld\n",l);
}main()
{for(reg int t=read();t--;work());
}

C

对偶一下,然后写个暴力 dp。(可能不对偶也行)

根据暴力 dp 的转移方式,容易发现 dp 数组是凸的,于是直接用平衡树维护即可。

#include<bits/stdc++.h>
#define IL inline
#define reg register
#define int long long
#define N 2000200
#define oo (1ll<<60)
IL int read()
{reg int x=0,f=0; reg char ch=getchar();while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return f?-x:x;
}IL void cmax(reg int &x,reg int y){x<y?x=y:0;}const int B=1e6;
int n,w[N],c[N];
std::mt19937 rnd((unsigned long long)(new char));int ls[N],rs[N],sz[N],sum[N],rd[N],val[N],ct[N],rt,tot;
bool tag1[N];
int tag2[N];IL int newnode(reg int w,reg int c)
{rd[++tot]=rnd();sz[tot]=ct[tot]=c;sum[tot]=c*w,val[tot]=w;return tot;
}IL void pushup(reg int o)
{sz[o]=sz[ls[o]]+sz[rs[o]]+ct[o];sum[o]=sum[ls[o]]+sum[rs[o]]+val[o]*ct[o];
}IL void apply1(reg int o){if(o)std::swap(ls[o],rs[o]),val[o]*=-1,sum[o]*=-1,tag1[o]^=1,tag2[o]*=-1;}
IL void apply2(reg int o,reg int k){if(o)val[o]+=k,sum[o]+=k*sz[o],tag2[o]+=k;}IL void pushdown(reg int o)
{if(tag1[o])apply1(ls[o]),apply1(rs[o]),tag1[o]=0;if(tag2[o])apply2(ls[o],tag2[o]),apply2(rs[o],tag2[o]),tag2[o]=0;
}int merge(reg int x,reg int y)
{if(!x||!y)return x|y;if(rd[x]<rd[y]){pushdown(x),rs[x]=merge(rs[x],y);return pushup(x),x;}pushdown(y),ls[y]=merge(x,ls[y]);return pushup(y),y;
}void split1(reg int o,reg int k,reg int &x,reg int &y) // siz
{if(!o)return x=y=0,void();pushdown(o);if(sz[ls[o]]+ct[o]<=k)x=o,split1(rs[o],k-sz[ls[o]]-ct[o],rs[o],y);else if(sz[ls[o]]>=k)y=o,split1(ls[o],k,x,ls[o]);else{reg int nc=k-sz[ls[o]];reg int u=newnode(val[o],ct[o]-nc);ct[o]=nc,rs[u]=rs[o],rs[o]=ls[u]=0;pushup(x=o),pushup(y=u);return;}pushup(o);
}void split2(reg int o,reg int k,reg int &x,reg int &y) // val
{if(!o)return x=y=0,void();pushdown(o);if(val[o]>=k)x=o,split2(rs[o],k,rs[o],y);else y=o,split2(ls[o],k,x,ls[o]);pushup(o);    
}int dfs(reg int o,reg int k)
{if(!o)return k;pushdown(o);k=dfs(ls[o],k);for(reg int i=0;i<ct[o];++i)k+=val[o],printf("%lld ",k);return dfs(rs[o],k);
}IL void print(reg int f0)
{printf("%lld ",f0);dfs(rt,f0);puts("");
}IL int max(reg int x,reg int y){return x>y?x:y;}main()
{n=read();for(reg int i=1;i<=n;++i)w[i]=read();for(reg int i=2;i<=n;++i)c[i]=read();rt=newnode(w[1],B);reg int f0=0,up=B;for(reg int i=2,x,y;i<=n;++i){if(up>c[i]){up=c[i];split1(rt,up,x,y);rt=x;}// print(f0);split2(rt,0,x,y);rt=merge(x,newnode(0,sz[y]+max(0,c[i]-up)));if(up<c[i])up=c[i];// print(f0);f0+=sum[rt],apply1(rt);// print(f0);apply2(rt,w[i]);// print(f0);split2(rt,0,x,y);// printf("[%lld, %lld]\n",f0,sum[x]);printf("%lld\n",f0+sum[x]);rt=merge(x,y);}// for(reg int i=2,j;i<=n;++i)// {//     for(j=c[i]+1;j<=B;++j)f[j]=-oo;//     for(j=1;j<=c[i];++j)cmax(f[j],f[j-1]);//     std::reverse(f,f+c[i]+1);//     for(j=0;j<=c[i];++j)f[j]+=w[i]*j;//     reg int ans=-oo;//     for(j=0;j<=c[i];++j)cmax(ans,f[j]);//     printf("%lld\n",ans);// }
}

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

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

相关文章

为什么选择持续绩效管理(CPM)

组织变革和发展的关键始于你的员工基础。要想在组织中建立一个不断发展和创新的环境,你必须确保你的员工是以目标、绩效和反馈为导向的。 #持续绩效管理#鼓励上级和下级之间建立直接的双向沟通。一个持续的绩效评估可以确保平稳有效的联系,随着时间的推移,可以看到更好的结果…

unity直接安装插件

一共三步 1.窗口->包管理器2. 在弹出的界面里点左上角的加号 依次解读选项为disk 文件夹(zip压缩文件请提前解压)tarball 压缩包(只支持tar压缩包)git URL 网址下载(国内应该得设置代理)by name 指定软件和版本下载 3.以disk为例,进入解压的地方选中package.json接着…

北航计网课程笔记-四、网络层

第四章 网络层 本章重点 1、IP数据报的格式和分片 2、IP地址的表示和分类分配、子网掩码、地址有效性、广播地址 3、子网划分 4、CIDR路由聚合 5、ARP协议和ICMP协议 6、路由表、路由器的工作原理 7、RIP协议和OSPF协议 8、网络层的综合设计和应用 网络层的功能 网络层的主要任…

北航计网课程笔记-六、应用层

第六章 应用层 应用层概述 应用层对应用程序的通信提供服务。应用层的功能:文件传输、访问和管理 电子邮件 虚拟终端 查询服务和远程作业登录应用层的重要协议FTP SMTP、POP3 HTTP DNS网络应用模型 客户/服务器模型C/S客户是服务请求方,服务器是服务提供方 Web、FTP、远程登录…

北航计网课程笔记-七、一些总结

复习到最后想开摆了,也没总结啥,只是一些格式……一些总结MAC帧格式IP数据报格式 IP首部20B~60B IP总长最多65535BTCP报文格式 TCP首部20B~60B 数据部分最多65535-20-20 = 65495BUDP报文格式UDP&TCP伪首部格式HTTP报文格式

北航计网课程笔记-一、概述

写在前面:本笔记根据王道408完成,北航软院不考的内容不在其中。 总之复习期末把王道刷一遍就行了。 个人学习用,如有错误敬请指正。第一章 概述 计算机网络概念 计算机网络的定义:一些互联的、自治的计算机的集合,主体是多台计算机,媒介为通信媒介, 目的是通信与资源共享…

北航计网课程笔记-二、物理层

第二章 物理层 物理层的任务:将原始的比特流从一台机器上传输到另一台机器上。 确定与传输媒体的接口特性:机械、电气、功能、规程通信基础 一些基本概念数据,信号和码元数据是传送信息的实体;信号是数据的电气或电磁表现;码元是数字通信中数字信号的计量单位,1码元可以携…

Winform和MFC的一个区别

前段时间我嫌桌面快捷键太多,我使用C语言用MFC制作了桌面自定义系统(上图左),可是这个系统存在一些问题,比如(下图) 默认情况下它的右上角没有最大化和最小化的按钮,而Winform是有的(下图)。 还有一个问题:在任务栏,点击时MFC不能最小化,而Winform可以;还有一个很…

应用中的 PostgreSQL项目案例

title: 应用中的 PostgreSQL项目案例 date: 2025/2/3 updated: 2025/2/3 author: cmdragon excerpt: 随着大数据和云计算的兴起,企业在数据管理和数据分析方面面临着越来越复杂的挑战。PostgreSQL 作为一个开源关系型数据库,凭借其卓越的扩展性和强大的功能,逐渐成为众多企业…

来自aakennes的新年祝福

来自aakennes的新年祝福组题人: @aakennes \(A\) P888. 字符串会上树 \(AC\)基础字符串。点击查看代码 string s,t="",w=""; map<string,string>f; int main() { // #define Isaac #ifdef Isaacfreopen("in.in","r",stdin);fr…

1.3 决定程序流程的程序计数器

CPU先执行0100 CPU每执行一个指令,程序计数器的值就会自动加1 CPU的控制器就会参照程序计数器的数值,从内存中读取命令并执行。 程序计数器决定着程序的流程

【每日一题】20250203

你是万千星球的星球! 你是沸腾的准则!你是精心保存的潜伏的萌芽!你是核心!【每日一题】我国发射的“天宫一号”和“神州八号”在对接前,”天宫一号”的运行轨道高度为 \(350 \; \mathrm{km}\),“神州八号”的运行轨道高度为 \(343 \; \mathrm{km}\).它们的运行轨道均视为…