JOI 2016 Final
链接
B. Collecting Stamps 2
考虑如果加的是 J
显然会加在最前面。如果加的是 I
会加在最后面,如果是 O
效果是增加前面的 J
数量乘上后面的 I
数量,分类讨论一下就好了。复杂度 。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100010;
char s[N];
ll f[3];
int main()
{
int n;scanf("%d%s",&n,s+1);
f[0]=f[1]=f[2]=0;
for(int i=n;i;i--){if(s[i]=='I') f[0]++;else if(s[i]=='O') f[1]+=f[0];else f[2]+=f[1];}
ll ans=f[1]+f[2],res=f[2];
f[0]=f[1]=f[2]=0;f[0]++;
for(int i=n;i;i--){if(s[i]=='I') f[0]++;else if(s[i]=='O') f[1]+=f[0];else f[2]+=f[1];}
ans=max(ans,f[2]);
int w0=0,w1=0;
for(int i=1;i<=n;i++) if(s[i]=='J') w0++;
for(int i=n;i;i--){if(s[i]=='J') w0--;else if(s[i]=='I') w1++;ans=max(ans,res+1ll*w0*w1);}
printf("%lld\n",ans);
return 0;
}
C. Train Fare
考虑一条边从 变成 相当于这条边被断掉了。实际上只要对每个点求出到 所有最短路径都被断掉的时刻即可。
可以认为一个点最短路变化的时候,这个点就被删掉了。直接 BFS 过程中转移每个点被删除的时间即可。
复杂度 。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define N 200010
using namespace std;
int nxt[N<<1],to[N<<1],w[N<<1],head[N],cnt;
void add(int u,int v,int w0){nxt[++cnt]=head[u];w[cnt]=w0;to[cnt]=v;head[u]=cnt;}
int x[N],y[N],t[N],f[N],g[N],ans[N];
queue<int>q;
int main()
{
int n,m,k;scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++) scanf("%d%d",&x[i],&y[i]),t[i]=m+1;
for(int i=1,x;i<=k;i++) scanf("%d",&x),t[x]=i;
for(int i=1;i<=m;i++) add(x[i],y[i],t[i]),add(y[i],x[i],t[i]);
memset(f,-1,sizeof(f));
q.push(1),f[1]=0,g[1]=k+1;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(f[v]==-1) f[v]=f[u]+1,g[v]=min(g[u],w[i]),q.push(v);
if(f[v]==f[u]+1) g[v]=max(g[v],min(g[u],w[i]));
}
}
for(int i=1;i<=n;i++) ans[g[i]]++;
for(int i=1;i<=k+1;i++) ans[i]+=ans[i-1];
for(int i=1;i<=k;i++) printf("%d\n",ans[i]);
return 0;
}
D. Territory
设一轮操作结束后位置移动了 ,不妨假设 (如果不是可以调整,若 特判即可)。考虑将所有可以通过 后互相到达的点归到一起。容易发现这些点按照 构成若干个区间,而区间总数是 的。
枚举所有可能合法的等价类,相当于给定 组区间,问交的大小。直接四个指针扫一遍即可。
复杂度 。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define N 200010
using namespace std;
int nxt[N<<1],to[N<<1],w[N<<1],head[N],cnt;
void add(int u,int v,int w0){nxt[++cnt]=head[u];w[cnt]=w0;to[cnt]=v;head[u]=cnt;}
int x[N],y[N],t[N],f[N],g[N],ans[N];
queue<int>q;
int main()
{
int n,m,k;scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++) scanf("%d%d",&x[i],&y[i]),t[i]=m+1;
for(int i=1,x;i<=k;i++) scanf("%d",&x),t[x]=i;
for(int i=1;i<=m;i++) add(x[i],y[i],t[i]),add(y[i],x[i],t[i]);
memset(f,-1,sizeof(f));
q.push(1),f[1]=0,g[1]=k+1;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(f[v]==-1) f[v]=f[u]+1,g[v]=min(g[u],w[i]),q.push(v);
if(f[v]==f[u]+1) g[v]=max(g[v],min(g[u],w[i]));
}
}
for(int i=1;i<=n;i++) ans[g[i]]++;
for(int i=1;i<=k+1;i++) ans[i]+=ans[i-1];
for(int i=1;i<=k;i++) printf("%d\n",ans[i]);
return 0;
}
E. Geologic Fault
考虑倒过来处理,即维护最后在地表的点初始的深度。
将坐标旋转 ,容易发现每次操作是将某个前缀向下移,或者某个后缀向上右移。容易发现这些点仍然构成偏序关系,用一个线段树即可。
复杂度 。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 200010
using namespace std;
typedef long long ll;
struct node{
int x,d,l;
}p[N];
ll x[N],y[N];
struct seg_tree{
ll t[N<<2];
void build(int u,int l,int r)
{
t[u]=r-l+1;if(l==r) return;
int mid=(l+r)>>1;build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}
void insert(int u,int l,int r,int p,int d)
{
t[u]+=d;if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) insert(u<<1,l,mid,p,d);
else insert(u<<1|1,mid+1,r,p,d);
}
int qry(int u,int l,int r,ll d)
{
if(t[u]<=d) return r+1;if(l==r) return l;
int mid=(l+r)>>1;
if(d<t[u<<1]) return qry(u<<1,l,mid,d);
return qry(u<<1|1,mid+1,r,d-t[u<<1]);
}
}X,Y;
int main()
{
int n,q;scanf("%d%d",&n,&q);
for(int i=1;i<=q;i++) scanf("%d%d%d",&p[i].x,&p[i].d,&p[i].l);
X.build(1,1,n),Y.build(1,1,n);
ll res=0;
for(int i=1;i<=n;i++) x[i]=y[i]=1;
for(int i=q;i;i--)
{
if(p[i].d==1)
{
int q=X.qry(1,1,n,p[i].x);
if(q<=n) Y.insert(1,1,n,q,p[i].l*2),y[q]+=p[i].l*2;
res+=p[i].l*2;
}
else
{
int q=Y.qry(1,1,n,p[i].x+res);
if(q<=n) X.insert(1,1,n,q,p[i].l*2),x[q]+=p[i].l*2;
}
}
for(int i=1;i<=n;i++) x[i]+=x[i-1],y[i]+=y[i-1];
for(int i=1;i<=n;i++) printf("%lld\n",(-y[i]+x[i]+res)/2);
return 0;
}
本文来自博客园,作者:Flying2018,转载请注明原文链接:https://www.cnblogs.com/Flying2018/p/JOI2016Final.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理