csps模拟测试50反思
又考崩了,T1一眼秒掉错误思路,然后迅速码完,并码完错误暴力,对拍拍上,以为AC。T2想到了二维莫队,发现是子任务就没去打,一直在想别的,T3最后想到60分打法,没有打完,也没时间暴力,挂掉。T2还有一个读错题的锅,T了一个子任务。
考试一定要合理分配时间,确定自己算法的正确性,想到一个类似的算法要敢于去实现。
T1 施工
单调栈优化dp 改变dp定义是优化dp的重要方式
dp[i]表示第i个位置不变的最优答案。枚举j转移,$O(n^2)$,期望得分53
考虑优化,dp[i]只会由最多一个h比它大的j转移过来,维护单调栈即可。
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 1005
using namespace std;
inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<='')x=x*+c-,c=getchar();
return x*f;
}
int dp[N][N],h[N],mn[N][N][];
int main()
{
memset(dp,0x3f,sizeof dp);memset(mn,0x3f,sizeof mn);
int n=read(),c=read(),ans=0x7fffffff;
for(int i=;i<=n;i++)h[i]=read();
for(int i=h[];i<=;i++)dp[][i]=(i-h[])*(i-h[]);
mn[][h[]][]=dp[][h[]]-h[]*c;mn[][][]=dp[][]+*c;
for(int j=h[]+;j<=;j++)
mn[][j][]=min(mn[][j-][],dp[][j]-j*c);
for(int j=;j;j--)
{
mn[][j][]=min(mn[][j+][],dp[][j]+j*c);
}
for(int i=;i<=n;i++)
{
for(int j=h[i];j<=;j++)
dp[i][j]=min(mn[i-][j][]+j*c+(j-h[i])*(j-h[i]),mn[i-][j+][]-j*c+(j-h[i])*(j-h[i]));
mn[i][h[i]][]=dp[i][h[i]]-h[i]*c;mn[i][][]=dp[i][]+*c;
for(int j=h[i]+;j<=;j++)
mn[i][j][]=min(mn[i][j-][],dp[i][j]-j*c);
for(int j=;j;j--)
mn[i][j][]=min(mn[i][j+][],dp[i][j]+j*c);
}
for(int i=h[n];i<=;i++)ans=min(ans,dp[n][i]);
cout<<ans<<endl;
return ;
}
30分代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define N 1000005
using namespace std;
inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<='')x=x*+c-,c=getchar();
return x*f;
}
long long f[N],h[N],sum[N][];
int n,C;
inline long long solve(int l,int r,long long ll,long long rr)
{
if(l>r)return (l!=)*(r!=n)*abs(h[l-]-h[r+])*C;
long long a=r-l+,c=sum[r][]-sum[l-][]+C*((l!=)*h[l-]+h[r+]*(r!=n)),b=-(l!=)*C-(r!=n)*C-*(sum[r][]-sum[l-][]);
long long x=-1.0*b/a/+0.5;x=max(ll,x);x=min(rr,x);
return /*cout<<(long long)a*x*x+b*x+c+0.5<<endl,*/(double)a*x*x+b*x+c+0.5;
}
int main()
{
n=read(),C=read();
for(int i=;i<=n;++i)h[i]=read(),sum[i][]=sum[i-][]+h[i]*h[i],sum[i][]=sum[i-][]+h[i];
h[]=h[n+]=0x3f3f3f3f;memset(f,0x3f,sizeof f);
f[]=;
for(int i=;i<=n+;++i)
{
long long mx=;
for(int j=i-;~j;--j)
{
if(h[j]>=mx)f[i]=min(f[i],f[j]+solve(j+,i-,mx,min(h[i],h[j])));
mx=max(mx,h[j]);
if(mx>h[i])break;
}
}
cout<<f[n+]<<endl;
}
53分代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define N 1000005 using namespace std; inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<='')x=x*+c-,c=getchar();
return x*f;
}
long long f[N],h[N],sum[N][];
int n,C,st[N],top;
inline long long solve(int l,int r,long long ll,long long rr)
{
if(l>r)return (l!=)*(r!=n)*abs(h[l-]-h[r+])*C;
long long a=r-l+,c=sum[r][]-sum[l-][]+C*((l!=)*h[l-]+h[r+]*(r!=n)),b=-(l!=)*C-(r!=n)*C-*(sum[r][]-sum[l-][]);
long long x=-1.0*b/a/+0.5;x=max(ll,x);x=min(rr,x);
return a*x*x+b*x+c;
}
int main()
{
n=read(),C=read();
for(int i=;i<=n;++i)h[i]=read(),sum[i][]=sum[i-][]+h[i]*h[i],sum[i][]=sum[i-][]+h[i];
h[]=h[n+]=0x3f3f3f3f;memset(f,0x3f,sizeof f);
f[]=;
st[++top]=;
for(int i=;i<=n+;++i)
{
long long mx=;
while(top&&h[st[top]]<=h[i])f[i]=min(f[i],f[st[top]]+solve(st[top]+,i-,mx,h[st[top]])),mx=h[st[top--]];
if(top)f[i]=min(f[i],f[st[top]]+solve(st[top]+,i-,mx,h[i]));
st[++top]=i;
}
cout<<f[n+]<<endl;
}
AC代码
T2 蔬菜
二维莫队(留一个坑,以后一定要学一学回滚莫队,树上莫队)板子题
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
map<int,int>mp;
int t[],bl[],ans,q,s[][],b[],tot;
inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<='')x=x*+c-,c=getchar();
return x*f;
}
struct query{
int lx,ly,rx,ry,id,ans;
friend bool operator < (const query a,const query b)
{
if(bl[a.lx]!=bl[b.lx])return bl[a.lx]<bl[b.lx];
if(bl[a.ly]!=bl[b.ly])return bl[a.ly]<bl[b.ly];
if(bl[a.rx]!=bl[b.rx])return bl[a.rx]<bl[b.rx];
return a.ry<b.ry;
}
inline void init(int x){lx=read(),ly=read(),rx=read(),ry=read(),id=x;}
}Q[];
inline void add(int x,int y)
{
ans-=t[s[x][y]]*t[s[x][y]];
t[s[x][y]]++;
ans+=t[s[x][y]]*t[s[x][y]];
return ;
}
inline void del(int x,int y)
{
ans-=t[s[x][y]]*t[s[x][y]];
t[s[x][y]]--;
ans+=t[s[x][y]]*t[s[x][y]];
}
inline void Add(int lx,int ly,int rx,int ry)
{
for(register int i=lx;i<=rx;i++)
for(register int j=ly;j<=ry;j++)
add(i,j);
}
inline void Del(int lx,int ly,int rx,int ry)
{
for(register int i=lx;i<=rx;i++)
for(register int j=ly;j<=ry;j++)
del(i,j);
}
void work()
{
sort(Q+,Q+q+);
int lx=,ly=,rx=,ry=;
for(int i=;i<=q;i++)
{
while(lx>Q[i].lx)lx--,Add(lx,ly,lx,ry);
while(rx<Q[i].rx)rx++,Add(rx,ly,rx,ry);
while(ly>Q[i].ly)ly--,Add(lx,ly,rx,ly);
while(ry<Q[i].ry)ry++,Add(lx,ry,rx,ry); while(lx<Q[i].lx)Del(lx,ly,lx,ry),lx++;
while(rx>Q[i].rx)Del(rx,ly,rx,ry),rx--;
while(ly<Q[i].ly)Del(lx,ly,rx,ly),ly++;
while(ry>Q[i].ry)Del(lx,ry,rx,ry),ry--;
Q[i].ans=ans;
}
sort(Q+,Q+q+,[](query a,query b){
return a.id<b.id;
});
}
int main()
{
int r=read(),c=read();q=read();const int t=;
for(int i=;i<=;i++)bl[i]=(i-)/t+;
for(int i=;i<=r;i++)
for(int j=;j<=c;j++)
s[i][j]=read(),b[++tot]=s[i][j];
sort(b+,b+tot+);tot=unique(b+,b+tot+)-b-;
for(int i=;i<=tot;i++)mp[b[i]]=i;
for(int i=;i<=r;i++)
for(int j=;j<=c;j++)
s[i][j]=mp[s[i][j]];
for(int i=;i<=q;i++)Q[i].init(i);
work();
for(int i=;i<=q;i++)printf("%d\n",Q[i].ans);
return ;
}
T3 联盟
枚举断边,连边的时候出于最优的策略,会连接两条直径的中点,预处理即可。
直径的性质:不一定唯一,直径的中点是距离所有点距离最大值最小的点。
#include<cstdio>
#include<iostream>
#define N 300005
using namespace std;
int f[][N][],maxd,a,b,nxt[N<<],to[N<<],head[N],cnt=,pre[N],in[N<<],ff[N];
char v[N<<],cut[N<<];
int q[N],tot,ed[N],st[N];
inline void Add(int u,int v)
{
to[++cnt]=v;nxt[cnt]=head[u];
head[u]=cnt;
}
inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<='')x=x*+c-,c=getchar();
return x*f;
}
void dp(int x,int fa,int opt)
{
int mx=,sec=;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==fa)continue;
dp(y,x,opt);
if(f[opt][y][]+>mx)sec=mx,mx=f[opt][y][]+;
else if(f[opt][y][]+>sec)sec=f[opt][y][]+;
f[opt][x][]=max(f[opt][x][],f[opt][y][]);
}
f[opt][x][]=mx;
f[opt][x][]=max(mx+sec,f[opt][x][]);
}
void dfs1(int x,int fa,int dis)
{
if(dis>=maxd)a=x,maxd=dis;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==fa||cut[i])continue;
dfs1(y,x,dis+);
}
}
void dfs2(int x,int fa,int dis)
{
if(dis>=maxd)b=x,maxd=dis;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==fa||cut[i])continue;
pre[y]=i;ff[y]=x;
v[i]=;
dfs2(y,x,dis+);
}
}
int main()
{
int n=read(),ans=0x7f7f7f7f,len=;
for(int i=;i<n;i++)
st[i]=read(),ed[i]=read(),
Add(st[i],ed[i]),Add(ed[i],st[i]);
dfs1(,,);maxd=;dfs2(a,,);
for(int i=b;i;i=ff[i])in[pre[i]]=;len=maxd;
dp(a,,),dp(b,,);
for(int i=;i<n;i++)
{
if(v[i<<]&&in[i<<])
{
int l1=f[][ed[i]][],l2=f[][st[i]][],tmp=;
tmp=max(l1,max(l2,(l1+)/++(l2+)/));
if(tmp<ans)ans=tmp,q[tot=]=i;
else if(tmp==ans)q[++tot]=i;
}
else if(v[i<<|]&&in[i<<|])
{
int l1=f[][ed[i]][],l2=f[][st[i]][],tmp=;
tmp=max(l1,max(l2,(l1+)/++(l2+)/));
if(tmp<ans)ans=tmp,q[tot=]=i;
else if(tmp==ans)q[++tot]=i;
}
else if(v[i<<])
{
int tmp=len;
if(tmp<ans)ans=tmp,q[tot=]=i;
else if(tmp==ans)q[++tot]=i;
}
else if(v[i<<|])
{
int tmp=len;
if(tmp<ans)ans=tmp,q[tot=]=i;
else if(tmp==ans)q[++tot]=i;
}
}
printf("%d\n%d ",ans,tot);
for(int i=;i<=tot;i++)printf("%d ",q[i]);
puts("");int s,t;
cout<<st[q[]]<<' '<<ed[q[]]<<' ';
cut[q[]<<]=cut[q[]<<|]=;maxd=;
dfs1(st[q[]],,);maxd=,dfs2(a,,);len=maxd,maxd=;
for(int i=b,cnt=;i;i=ff[i],cnt++)
if(cnt==len/){cout<<i<<' ';break;}maxd=;
dfs1(ed[q[]],,);maxd=,dfs2(a,,);len=maxd,maxd=;
for(int i=b,cnt=;i;i=ff[i],cnt++)
if(cnt==len/){cout<<i<<' ';break;}
}
附上带修主席树代码
#include<cstdio>
#define N 100050
using namespace std;
const int inf=1e9;
int rt[N],a[N],n;
struct Segtree{
int s[N<<],ls[N<<],rs[N<<],tot,tmp[][],cnt[];
inline void up(int k){s[k]=s[ls[k]]+s[rs[k]];return ;}
void change(int &k,int l,int r,int pos,int val)
{
if(!k)k=++tot;
if(l==r){s[k]+=val;return ;}
int mid=l+r>>;
if(pos<=mid) change(ls[k],l,mid,pos,val);
else change(rs[k],mid+,r,pos,val);
up(k);
}
int query(int k,int l,int r,int ll,int rr)
{
if(l==ll&&r==rr)return s[k];
int mid=l+r>>;
if(ll<=mid)return query(ls[k],l,mid,ll,rr);
else return query(rs[k],mid+,r,ll,rr);
}
int __query(int l,int r,int k)
{
if(l==r)return l;
int mid=l+r>>,nowsum=;
for(int i=;i<=cnt[];i++) nowsum-=s[ls[tmp[][i]]];
for(int i=;i<=cnt[];i++) nowsum+=s[ls[tmp[][i]]];
if(nowsum>=k)
{
for(int i=;i<=cnt[];i++) tmp[][i]=ls[tmp[][i]];
for(int i=;i<=cnt[];i++) tmp[][i]=ls[tmp[][i]];
return __query(l,mid,k);
}
else
{
for(int i=;i<=cnt[];i++) tmp[][i]=rs[tmp[][i]];
for(int i=;i<=cnt[];i++) tmp[][i]=rs[tmp[][i]];
return __query(mid+,r,k-nowsum);
}
}
inline int _query(int l,int r,int k)
{
cnt[]=cnt[]=;
for(int i=l-;i;i-=i&-i) tmp[][++cnt[]]=rt[i];
for(int i=r;i;i-=i&-i) tmp[][++cnt[]]=rt[i];
return __query(-inf,inf,k);
}
inline void _change(int pos,int val,int opt)
{
int fr=a[pos];
for(;pos<=n;pos+=pos&-pos)
{
if(opt) change(rt[pos],-inf,inf,fr,-);
change(rt[pos],-inf,inf,val,);
}
return ;
}
}T;
int main()
{
int m;scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
T._change(i,a[i],);
}
while(m--)
{
char opt[];
scanf("%s",opt);
if(opt[]=='C')
{
int x,v;
scanf("%d%d",&x,&v);
T._change(x,v,);
a[x]=v;
}
else
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",T._query(l,r,x));
}
}
return ;
}
csps模拟测试50反思的更多相关文章
- [CSP-S模拟测试50]反思+题解
??大部分人都觉得T3是道不可做题去刚T1T2了,于是我就侥幸苟到了前面? 这场考试比较成功的就是快速水掉了T1T2的部分分,1h拿到88分起码为之后硬肝T3上了保险(赛后发现就算T3爆零也能rank ...
- 2019.10.30 csp-s模拟测试94 反思总结
头一次做图巨的模拟题OWO 自从上一次听图巨讲课然后骗了小礼物以后一直对图巨印象挺好的233 T1: 对于XY取对数=Y*log(x) 对于Y!取对数=log(1*2*3*...*Y)=log1+lo ...
- 2019.9.28 csp-s模拟测试54 反思总结
咕咕咕的冲动如此强烈x T1x: 看完题目想了想,感觉把gcd不为1的强行放在一组,看作一个连通块,最后考虑连通块之间的组合方式就可以了. 然后维护这个连通块可以写并查集可以连边跑dfs怎么着都行… ...
- csp-s模拟测试50(9.22)「施工(单调栈优化DP)」·「蔬菜(二维莫队???)」·「联盟(树上直径)」
改了两天,终于将T1,T3毒瘤题改完了... T1 施工(单调栈优化DP) 考场上只想到了n*hmaxn*hmaxn的DP,用线段树优化一下变成n*hmaxn*log但显然不是正解 正解是很**的单调 ...
- csps模拟测试92反思
连着挂了三天T1了. 89: SPFA$vst$数组没清空 90:调试的时候多删了一句代码 91:没开$long long$ 我真是废物. 希望以后不要犯SB错误了
- [CSP-S模拟测试48]反思+题解
状态很垃圾的一场考试.感觉“这么多分就够了”的心态很是在给自己拖后腿. 打开题面,第一页赫然写着:$Claris' Contest$. 吓得我差点手一抖关掉.不过后来想想似乎强到变态的人出的题都不是很 ...
- [CSP-S模拟测试47]反思+题解
打开题面,T3似乎被换过了.(那我就更有理由直接弃掉了) T1是我最害怕的乱搞题,赶紧扔了看T2.发现是个sb板子?雨天的尾巴弱化版? 然而线段树合并早忘干净了(最近几道可以线段树合并的题都是用别的方 ...
- 2019.10.29 csp-s模拟测试93 反思总结
T1: 求出前缀和,三维偏序O(nlog2n)CDQ 二维其实就可以 #include<iostream> #include<cstdio> #include<cstri ...
- 2019.10.29 csp-s模拟测试92 反思总结
今天快乐的墨雨笙因为什么而几乎爆零了呢? 顾此失彼+不会对拍+无脑的复杂度 今天高兴的墨雨笙又因为什么调了一个下午呢? 不明题意+不想范围+板子低级错误 R.I.P. T1: //唉 //害怕TLE, ...
随机推荐
- 色即是空,空即是色---java有关null的几件小事
故事背景 ---摩诃般若波罗蜜多心经: 观自在菩萨,行深般若波罗蜜多时,照见五蕴皆空,度一切苦厄.舍利子,色不异空,空不异色:色即是空,空即是色.受想行识,亦复如是.舍利子,是诸法空相,不生不灭,不垢 ...
- Nginx开启Gzip压缩提升页面加载速度
1.在 nginx 的conf 目录下新建 gzip.conf 文件 #开启gzip压缩 gzip on; #设置允许压缩的页面最小字节数 gzip_min_length 1k; #申请4个单位为16 ...
- C# 8 的模式匹配
C# 7 里面的Pattern Mathing is 模式 switch 和 when C# 8 里面的Pattern Matching 使用Deconstructor 和 位置匹配模式 下面两个类T ...
- Swoole4-swoole创建Mysql连接池
一 .什么是mysql连接池 场景:每秒同时有1000个并发,但是这个mysql同时只能处理400个连接,mysql会宕机. 解决方案:连接池,这个连接池建立了200个和mysql的连接,这1000个 ...
- 浅谈json web token及应用
Json Web Token (JWT),是一个非常轻巧的规范,这个规范允许在网络应用环境间客户端和服务器间较安全的传递信息.该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO) ...
- 如何使用Externalizable接口自定义Java中的序列化
Java序列化过程的缺点 我们都知道如何使用Serializable接口序列化/反序列化一个对象,并且如何使用writeObject 和readObject方法自定义序列化过程. 但是这些自定义还不够 ...
- Zabbix安装与简单配置
目录 0. 前言 1. 安装 1.1 准备安装环境 1.1.1 下载安装包 1.1.2 修改文件配置 1.2 开始安装 2. 实验环境 2.1 简易拓扑图 2.2 基本配置 3. 配置 0. 前言 不 ...
- unittest执行用例方法
#coding=utf-8 from selenium import webdriver from time import sleep import unittest#导入unittest库 impo ...
- PowerShell渗透--Empire
0x00 简介 Empire是一款针对Windows平台的,使用PowerShell脚本作为攻击载荷的渗透攻击框架代码具有从stager生成,提权到渗透维持的一系列功能,无需powershell.ex ...
- 学习 Antd Pro 前后端分离
1.前言 最近学习reactjs ,前些年用RN开发过移动端,入门还算轻松.现在打算使用 Antd Pro 实现前后端分离.要使用Antd Pro这个脚手架,必须熟悉 umi.dva.redux-sa ...