点我看题(Div2)

Div 2A. Likes

如果要赞最多,肯定是先放所有的点赞,再放所有移除的操作。如果要最少,那就先把赞分成两种:最后被移除的和没被移除的;最后先放所有被移除的,放一个移除一个,然后再把所有没被移除的接在最后即可。

时间复杂度\(O(n)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define fi first
#define se second
#define pb push_back
#define mpr make_pair void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int t,n,a[110],ans1[110],ans2[110]; int main()
{
fileio(); cin>>t;
rep(tn,t)
{
cin>>n;
int posi=0,nega=0;
rep(i,n) cin>>a[i];
rep(i,n) if(a[i]>0) ++posi;else ++nega;
int bigp=posi,bign=nega,smlp=posi,smln=nega,ansbig=0,anssml=0;
repn(i,n)
{
if(bigp)
{
--bigp;
++ansbig;
}
else
{
--bign;
--ansbig;
}
if(i<=nega*2)
{
if(i%2==1) ++anssml;
else --anssml;
}
else ++anssml;
ans1[i]=ansbig;ans2[i]=anssml;
}
repn(i,n) cout<<ans1[i]<<' ';cout<<endl;
repn(i,n) cout<<ans2[i]<<' ';cout<<endl;
} termin();
}

Div 2B. Settlement of Guinea Pigs

对每个时刻求出可能需要的最大猪圈数,然后取max即可。对于一个时刻,可以把猪分成两类,已经认证性别的和没认证的。没认证的只能自己住一个猪圈,因为和任意其他猪住一个都可能不合法。已经认证的,如果总数是>0的偶数,肯定是两类都是奇数个的情况最费猪圈;如果是奇数,那就是一类奇数一类偶数,猪圈数是固定的;总数是0那就是0个猪圈。

时间复杂度\(O(n)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define fi first
#define se second
#define pb push_back
#define mpr make_pair void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int t,n,a[100010]; int calc(int pre)
{
if(pre==0) return 0;
if(pre==1) return 1;
if(pre==2) return 2;
if(pre%2==0) return (pre-2)/2+2;
return (pre+1)/2;
} int main()
{
fileio(); cin>>t;
rep(tn,t)
{
cin>>n;
int pre=0,nxt=0,ans=0;
rep(i,n)
{
int x;scanf("%lld",&x);
if(x==1)
{
++nxt;
ans=max(ans,nxt+calc(pre));
}
else
{
pre+=nxt;nxt=0;
ans=max(ans,calc(pre));
}
}
cout<<ans<<endl;
} termin();
}

Div 1A/2C. The Very Beautiful Blanket

怎么每场都有猜谜题呢。。。

首先猜一个:不同数的最大个数是n*m,很多这种题都是先猜能达到最大值的

观察题目中的那个两个田字格异或和相等的限制,其实只要对\(2^0\cdots 2^{63}\)的每个bit都满足就行了。对于每个bit,发现如果我们只把一些行中所有的数都刷上这个bit,其他的行不刷,是满足限制的。比如我们令第1,3,5,6行所有的数都含有\(2^3\),其他的行都不含有,是符合限制的,这时每个田字格的异或和都是0。发现使用这种刷一行或一列的方式,我们可以让矩阵中的所有数都不同。比如我们令数组\(a=\{0,1,2,\cdots 9\},b=\{10,11,12\cdots 19\}\)。矩阵中第i行j列的数含有\(2^{a_k}\)当且仅当i中含有\(2^k\),含有\(2^{b_k}\)当且仅当j中含有\(2^k\)。这么操作其实就是给一些行和一些列都刷上了某一个bit,且成功区别开了所有行和所有列,使得矩阵中每一个数都不同。

时间复杂度\(O(nmlognlogm)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define fi first
#define se second
#define pb push_back
#define mpr make_pair void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int t,n,m,ans[210][210];
vector <int> r,c; int main()
{
fileio(); rep(i,10) r.pb(1<<i);
for(int i=10;i<20;++i) c.pb(1<<i);
cin>>t;
rep(tn,t)
{
cin>>n>>m;
rep(i,n) rep(j,m)
{
ans[i][j]=0;
rep(k,r.size()) if(i&(1<<k)) ans[i][j]|=r[k];
rep(k,c.size()) if(j&(1<<k)) ans[i][j]|=c[k];
}
cout<<n*m<<endl;
rep(i,n)
{
rep(j,m) printf("%d ",ans[i][j]);
puts("");
}
} termin();
}

Div 1B/2D. Buying gifts

先把所有department按\(a_i\)从小到大排序,枚举给第一个人买的礼物最大值\(a_i\),此时i右侧的必须全买给第二个人,左侧的可以给第一个人也可以给第二个人。首先令i右侧的\(b_i\)最大值为\(mx\),如果\(mx\ge a_i\),此时的答案就是\(mx-a_i\);否则可以在i左侧的\(b_i\)中找一个与\(a_i\)最接近的再次更新答案,可以用multiset实现。需要特判一下\(i=n\)的情况。

时间复杂度\(O(nlogn)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <LL,LL>
#define fi first
#define se second
#define pb push_back
#define mpr make_pair void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; LL t,n;
vector <pii> a;
multiset <LL> l,r; LL findNearL(LL x)
{
auto it=l.lower_bound(x);
pii ret=mpr(1e18,1e18);
if(it!=l.end()) ret=min(ret,mpr(llabs(*it-x),*it));
if(it!=l.begin())
{
--it;
ret=min(ret,mpr(llabs(*it-x),*it));
}
return ret.se;
} int main()
{
fileio(); cin>>t;
rep(tn,t)
{
cin>>n;
a.clear();
LL x,y;
rep(i,n)
{
scanf("%lld%lld",&x,&y);
a.pb(mpr(x,y));
}
sort(a.begin(),a.end());
l.clear();r.clear();
rep(i,a.size()) r.insert(a[i].se);
LL ans=1e18;
rep(i,a.size())
{
r.erase(r.lower_bound(a[i].se));
if(i-1>=0) l.insert(a[i-1].se);
if(i==a.size()-1) break;
LL mx2=*r.rbegin();
ans=min(ans,llabs(mx2-a[i].fi));
if(mx2<a[i].fi&&l.size())
{
LL val=findNearL(a[i].fi);
ans=min(ans,llabs(val-a[i].fi));
}
}
LL val=findNearL(a.back().fi);
ans=min(ans,llabs(val-a.back().fi));
cout<<ans<<endl;
} termin();
}

Div 1C/2E. Music Festival

首先令\(mx_i\)表示第i个专辑中的最大值,发现如果一个mx小的专辑排在一个mx大的专辑后面(mx相等也一样),那这个专辑是不能产生任何贡献的。所以可以先把所有专辑按\(mx_i\)从小到大排序,我们现在要在其中选一些使得前缀最大值的个数最多。可以用dp实现,\(dp_{i,j}\)表示处理到第i个专辑,此时被选的专辑中mx的最大值为j的最大前缀最大值个数。这状态是\(O(n^2)\)的,但是在处理每个i时改变的状态数都很少,所以可以用线段树维护j这一维,转移时枚举当前专辑中得到的前缀最大值个数,就能得到可以从其转移的j的范围,在线段树上询问即可。注意事项:每个测试点不能直接清空整个线段树,会TLE,要先把值域离散化后清空要用的部分。

时间复杂度\(O(nlogn)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define fi first
#define se second
#define pb push_back
#define mpr make_pair void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; int t,n;
vector <pair <int,vector <int> > > v;
vector <int> dsc; int getDSC(int x){return lower_bound(dsc.begin(),dsc.end(),x)-dsc.begin();} namespace st
{
int n2,dat[800010];
void upd(int k,int val)
{
dat[k]=max(dat[k],val);
while(k>0)
{
k=(k-1)/2;
dat[k]=max(dat[k],val);
}
}
int qry(int k,int lb,int ub,int tlb,int tub)
{
if(ub<tlb||tub<lb) return 0;
if(tlb<=lb&&ub<=tub) return dat[k];
return max(qry(k+k+1,lb,(lb+ub)/2,tlb,tub),qry(k+k+2,(lb+ub)/2+1,ub,tlb,tub));
}
} int main()
{
fileio(); cin>>t;
rep(tn,t)
{
cin>>n;
v.clear();dsc.clear();
rep(i,n)
{
int x,y,mx=-1e9;vector <int> tmp;
scanf("%d",&x);
rep(j,x)
{
scanf("%d",&y);
mx=max(mx,y);tmp.pb(y);dsc.pb(y);
}
v.pb(mpr(mx,tmp));
}
sort(v.begin(),v.end());
sort(dsc.begin(),dsc.end());dsc.erase(unique(dsc.begin(),dsc.end()),dsc.end());
rep(i,v.size()) rep(j,v[i].se.size()) v[i].se[j]=getDSC(v[i].se[j]);
st::n2=1;while(st::n2<dsc.size()) st::n2*=2;
rep(i,st::n2*2+3) st::dat[i]=0;
rep(i,v.size())
{
vector <int> premx;
int mx=-1;
rep(j,v[i].se.size()) if(v[i].se[j]>mx)
{
mx=v[i].se[j];
premx.pb(mx);
}
int opt=-1;
rep(i,premx.size())
{
int lb=(i==0 ? 0:premx[i-1]),ub=premx[i]-1;
int val=st::qry(0,0,st::n2-1,lb,ub)+premx.size()-i;
opt=max(opt,val);
}
st::upd(premx.back()+st::n2-1,opt);
}
cout<<st::dat[0]<<endl;
} termin();
}

Div 1D/2F. The way home

无论是cf还是atc,这种用比较复杂的状态跑最短路的题还是经常有的。

先明确我们走的思路:当要坐某趟航班钱不够时,就在我们走到过的报酬最高的城市不断补表演,直到钱够做这次航班为止。

令\(dist_{i,j}\)表示当前走到i号点,在这次走到i号点之前经过的\(w\)最大的点的编号为j,此时的最小表演数和最大剩余钱数(先按最小表演数从小到大排序,相同的再按剩余钱数从大到小排序)。我们来证明:如果\(dist_{i,j}\)有两个可能的状态\(\{a,b\}\)和\(\{c,d\}\)(ac表示最小表演数,bd表示钱数),且a<c,b<d,此时第一个状态一定优于第二个。用一种类似归纳的思想,我们假设已经对这两个状态转移过来的路径上的所有\(dist_{i,j}\)都证明了其最优状态唯一。由于这两个状态在这次到i之前经过的报酬最高的点都是j,因此它们是从同一个\(dist_{j,*}\)转移过来的,在那之后它们的表演数才变得不同。因此第二个状态的d肯定\(<w_j\),因为我们补表演是补到能坐航班就停了,所以剩下的一定\(<w_j\)。因此如果给第一个状态补\(c-a\)次表演,使两个状态表演次数相同,第一个的钱数一定比第二个多,所以第一个一定更优。

然后就用上面的状态跑一个Dijkstra就行了,时间复杂度\(O(nmlog(n^2))\)(可能?没仔细算)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <LL,LL>
#define fi first
#define se second
#define pb push_back
#define mpr make_pair void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
} using namespace std; LL t,n,m,p,w[810];
vector <pii> g[810];
pii dist[810][810];
priority_queue <pair <pii,pii> > q; int main()
{
fileio(); cin>>t;
rep(tn,t)
{
cin>>n>>m>>p;
repn(i,n) scanf("%lld",&w[i]);
rep(i,n+3) g[i].clear();
LL x,y,z;
rep(i,m)
{
scanf("%lld%lld%lld",&x,&y,&z);
g[x].pb(mpr(y,z));
}
rep(i,n+3) rep(j,n+3) dist[i][j]=mpr(-1e18,-1e18);
dist[1][0]=mpr(0,p);
q.push(mpr(mpr(0,p),mpr(1,0)));
while(!q.empty())
{
auto fr=q.top();q.pop();
pii val=fr.fi;LL pos=fr.se.fi,opt=fr.se.se;
if(dist[pos][opt]>val) continue;
if(w[pos]>w[opt]) opt=pos;
rep(i,g[pos].size())
{
pii nval=val;
if(nval.se<g[pos][i].se)
{
LL add=(g[pos][i].se-nval.se+w[opt]-1)/w[opt];
nval.fi-=add;nval.se+=add*w[opt];
}
nval.se-=g[pos][i].se;
if(dist[g[pos][i].fi][opt]<nval)
{
dist[g[pos][i].fi][opt]=nval;
q.push(mpr(nval,mpr(g[pos][i].fi,opt)));
}
}
}
pii ans=mpr(-1e18,-1e18);
repn(i,n) ans=max(ans,dist[n][i]);
if(ans.fi< -1e17) puts("-1");
else cout<< -ans.fi<<endl;
} termin();
}

由于我用小号打的Div2,所以看不到过了一车的那个1F,1E也不会。后面如果有时间会更新1E和1F的题解

Codeforces Round #857 Div.1/Div.2 CF1801/1802 2A~2F 题解的更多相关文章

  1. Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...

  2. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

  3. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  4. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

  5. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...

  6. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...

  7. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  8. Educational Codeforces Round 39 (Rated for Div. 2) G

    Educational Codeforces Round 39 (Rated for Div. 2) G 题意: 给一个序列\(a_i(1 <= a_i <= 10^{9}),2 < ...

  9. Educational Codeforces Round 48 (Rated for Div. 2) CD题解

    Educational Codeforces Round 48 (Rated for Div. 2) C. Vasya And The Mushrooms 题目链接:https://codeforce ...

  10. Educational Codeforces Round 60 (Rated for Div. 2) 题解

    Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...

随机推荐

  1. Navicat连接Oracle时报错ORA-28547:完美解决

    1. 先用你的IDEA或者别人的连接到oracle数据库(为了查询版本) 1.1 查询版本SQL:select * from v$version; 2. 引入对应的oci.dll文件 链接:https ...

  2. Ubuntu 20.04 部署Prmoetheus+grafana+mysql+mysqld_exporter+node_exporter

    Prometheus简介 Prometheus是一个功能强大的开源监控系统,可从您的服务中收集指标并将其存储在时间序列数据库中.它通过Grafana等工具提供多维数据模型,灵活的查询语言和多样化的可视 ...

  3. docker-compose之memcached

    新建docker-compose.yml,写入以下内容 memcached: image: memcached:latest ports: - 11211:11211 启动服务 docker-comp ...

  4. 6. Python 模块

    模块其实就是一个python文件 python导入模块的顺序 1. 从当前目录下找需要导入的python文件 2. 从python的环境变量中找 sys.path 当前目录和sys.path中都有im ...

  5. 问题:配置apache的相关配置文件报错:Invalid command 'Order' (已解决)

    1. 问题描述 在虚拟文件httpd-vhosts.conf里面,directory里加入Order allow,deny,重启apache,出现Invalid command 'Order', pe ...

  6. flutter List使用

    _tabbarTitile.map((e){ return Tab( text: e, ); }).toList(),

  7. vue中页面渲染完成之后获取元素的属性

    data() { return { message : [], }; }, watch:{ message:function(){ this.$nextTick(function(){ //方法 }) ...

  8. 在Unity3D中开发的Sketch Shader

    Pencil Sketch Shader 特点 此素描渲染风格的Shader是顶点片元Shader,由本人手动编写完成. 此素描渲染风格的Shader已经在移动设备真机上进行过测试,可以直接应用到您的 ...

  9. 医学分割 不确定性 2019 MICCAI

    z今天分享一篇发表在MICCAI 2019上的论文: Uncertainty-aware Self-ensembling Model for Semi-supervised 3D Left Atriu ...

  10. sequelize的创建接口以及模糊查询

    第一步: 在routes里面复制index.js更改为xxx.js(例如arctile.js) res.json()返回的就是json文件 第二步: 在views里app.js引用路由 第三步:查找数 ...