Codeforces 863 简要题解
传送门
简要题解?因为最后一题太毒不想写了所以其实是部分题解。。。
A题
传送门
题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数。
思路:直接模拟。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
int cnt[10];
char s[20];
int main(){
scanf("%s",s+1);
int l=1,r=strlen(s+1);
while(s[l]=='0'&&l!=r)++l;
if(l==r)return puts("YES"),0;
while(s[r]=='0')--r;
while(l<r){
if(s[l]!=s[r])return puts("NO"),0;
++l,--r;
}
puts("YES");
return 0;
}
B题
传送门
题意:有2n2n2n个人坐船,每个人有重量,n−1n-1n−1艘双人船和222艘单人船,双人船的代价是乘坐的两个人重量差的绝对值,问所有人坐上船的最小代价。
思路:枚举哪两个坐单人船暴力更新答案。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=1055;
int n,w[N],a[N],ans=0x3f3f3f3f;
inline void solve(){
int sum=0;
for(ri i=1;i<=n*2-2;i+=2)sum+=a[i+1]-a[i];
ans=min(ans,sum);
}
int main(){
n=read();
for(ri i=1;i<=n*2;++i)w[i]=read();
sort(w+1,w+n*2+1);
for(ri i=1;i<=n*2;++i){
for(ri j=i+1;j<=n*2;++j){
int tot=0;
for(ri k=1;k<=n*2;++k)if(k!=i&&k!=j)a[++tot]=w[k];
solve();
}
}
cout<<ans;
return 0;
}
C题
传送门
题意:两个机器人猜拳,出拳可能为1,2,31,2,31,2,3中的一个,当局面为(i,j)(i,j)(i,j)时AAA下一轮会出Ai,jA_{i,j}Ai,j,BBB下一轮会出Bi,jB_{i,j}Bi,j,问最后两个机器人的积分。
思路:显然出拳序列是一个ρ\rhoρ型的,把环找出来即可。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
typedef pair<int,int> pii;
typedef long long ll;
const int N=1055;
vector<pii>turn;
vector<pii>sum;
ll k;
int a,b;
pii trans[4][4];
map<pii,int>vis;
inline int check(int a,int b){
if(a==2&&b==1)return 1;
if(a==3&&b==2)return 1;
if(a==1&&b==3)return 1;
return 0;
}
int main(){
scanf("%lld",&k),a=read(),b=read();
for(ri i=1;i<=3;++i)for(ri j=1;j<=3;++j)trans[i][j].fi=read();
for(ri i=1;i<=3;++i)for(ri j=1;j<=3;++j)trans[i][j].se=read();
turn.push_back(pii(0,0)),sum.push_back(pii(0,0));
turn.push_back(pii(a,b)),sum.push_back(pii(check(a,b),check(b,a)));
for(ri i=1;i<k;++i){
pii tmp=turn[i],nxt=trans[tmp.fi][tmp.se],pts=sum[i];
vis[tmp]=i;
if(vis[nxt]){
int tim=vis[nxt],len=i-tim+1,ttmp=(k-tim+1)%len;
pii ans=sum[tim-1+ttmp];
ll a1=ans.fi,a2=ans.se;
a1+=(k-tim+1)/len*(pts.fi-sum[tim-1].fi),a2+=(k-tim+1)/len*(pts.se-sum[tim-1].se);
cout<<a1<<' '<<a2;
return 0;
}
turn.push_back(nxt),sum.push_back(pii(pts.fi+check(nxt.fi,nxt.se),pts.se+check(nxt.se,nxt.fi)));
}
cout<<sum[k].fi<<' '<<sum[k].se<<'\n';
return 0;
}
D题
传送门
题意:给一个序列,支持区间右移,区间翻转,问最后的序列。
思路:加强版文艺平衡树。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=4e5+5;
typedef pair<int,int> pii;
int n,m,q;
namespace bst{
#define lc (son[p][0])
#define rc (son[p][1])
int val[N],rd[N],siz[N],rev[N],rt=0,tot=0,son[N][2];
inline int build(int v){return val[++tot]=v,rd[tot]=rand(),siz[tot]=1,son[tot][0]=son[tot][1]=0,tot;}
inline void pushup(int p){siz[p]=siz[lc]+1+siz[rc];}
inline void pushnow(int p){rev[p]^=1,swap(son[p][0],son[p][1]);}
inline void pushdown(int p){
if(!rev[p])return;
if(lc)pushnow(lc);
if(rc)pushnow(rc);
rev[p]=0;
}
inline int merge(int a,int b){
if(!a||!b)return a+b;
pushdown(a),pushdown(b);
if(rd[a]>rd[b])return son[a][1]=merge(son[a][1],b),pushup(a),a;
return son[b][0]=merge(a,son[b][0]),pushup(b),b;
}
inline pii split(int p,int k){
if(!p)return pii(0,0);
pii tmp;
pushdown(p);
if(siz[lc]>=k)return tmp=split(lc,k),lc=tmp.se,pushup(p),pii(tmp.fi,p);
return tmp=split(rc,k-siz[lc]-1),rc=tmp.fi,pushup(p),pii(p,tmp.se);
}
inline void insert(int id,int v){
pii x=split(rt,id-1);
rt=merge(merge(x.fi,build(v)),x.se);
}
inline void delet(int id){
pii x=split(rt,id-1),y=split(x.se,1);
rt=merge(x.fi,y.se);
}
inline int query(int id){
pii x=split(rt,id-1),y=split(x.se,1);
int ret=val[y.fi];
return rt=merge(x.fi,merge(y.fi,y.se)),ret;
}
inline void update(int l,int r){
pii x=split(rt,l-1),y=split(x.se,r-l+1);
pushnow(y.fi),rt=merge(x.fi,merge(y.fi,y.se));
}
#undef lc
#undef rc
}
int main(){
srand(time(NULL));
n=read(),q=read(),m=read();
for(ri i=1;i<=n;++i)bst::insert(i,read());
while(q--){
int op=read(),l=read(),r=read();
if(op==1){
int tmp=bst::query(r);
bst::delet(r);
bst::insert(l,tmp);
}
else bst::update(l,r);
}
for(ri i=1;i<=n;++i)cerr<<bst::query(i)<<' ';
puts("");
for(ri i=1;i<=m;++i)cout<<bst::query(read())<<' ';
return 0;
}
E题
传送门
题意:给一些线段,输出任意一条满足以下条件的线段:
去掉它之后覆盖的总长度不变。
思路:离散化之后差分/线段树。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=6e5+5;
int n,m=0,val[N];
struct node{int l,r;}a[N];
namespace SGT{
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
int mn[N<<2],add[N<<2];
inline void pushup(int p){mn[p]=min(mn[lc],mn[rc]);}
inline void pushnow(int p,int v){mn[p]+=v,add[p]+=v;}
inline void pushdown(int p){if(add[p])pushnow(lc,add[p]),pushnow(rc,add[p]),add[p]=0;}
inline void update(int p,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return pushnow(p,1);
pushdown(p);
if(qr<=mid)update(lc,l,mid,ql,qr);
else if(ql>mid)update(rc,mid+1,r,ql,qr);
else update(lc,l,mid,ql,mid),update(rc,mid+1,r,mid+1,qr);
pushup(p);
}
inline int query(int p,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return mn[p];
pushdown(p);
if(qr<=mid)return query(lc,l,mid,ql,qr);
if(ql>mid)return query(rc,mid+1,r,ql,qr);
return min(query(lc,l,mid,ql,mid),query(rc,mid+1,r,mid+1,qr));
}
}
int main(){
n=read();
for(ri i=1;i<=n;++i)val[++m]=a[i].l=read(),val[++m]=a[i].r=read(),val[++m]=a[i].l-1;
sort(val+1,val+m+1),m=unique(val+1,val+m+1)-val-1;
for(ri i=1;i<=n;++i){
a[i].l=lower_bound(val+1,val+m+1,a[i].l)-val;
a[i].r=lower_bound(val+1,val+m+1,a[i].r)-val;
SGT::update(1,1,m,a[i].l,a[i].r);
}
for(ri i=1;i<=n;++i)if(SGT::query(1,1,m,a[i].l,a[i].r)>1)return cout<<i,0;
puts("-1");
return 0;
}
F题
传送门
题意:
现在有nnn个数,mmm个限制。每个数只能为111到nnn,限制表示为一个区间中所有数不小于/不大于某个数,最后的代价是∑i=1ncnti2\sum_{i=1}^ncnt_i^2∑i=1ncnti2,问最小代价。
思路:直接按照题意模拟跑费用流。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=205,M=100005;
int n,m,up[N],down[N];
namespace mcmf{
int d[N],first[N],pred[N],pos[N],F,s,t,cnt;
bool in[N];
struct edge{int v,next,c,w;}e[M];
inline void addedge(int u,int v,int c,int w){e[++cnt]=(edge){v,first[u],c,w},first[u]=cnt;}
inline void add(int u,int v,int c,int w){cerr<<u<<' '<<v<<' '<<c<<' '<<w<<'\n',addedge(u,v,c,w),addedge(v,u,0,-w);}
inline void init(){cnt=-1,memset(first,-1,sizeof(first)),F=0,s=0,t=2*n+1;}
inline bool bfs(){
static int q[N],hd,tl;
for(ri i=s;i<=t;++i)d[i]=0x3f3f3f3f;
d[q[hd=tl=1]=s]=0;
while(hd<=tl){
int x=q[hd++];
in[x]=0;
for(ri i=first[x],v;~i;i=e[i].next){
if(e[i].c&&d[v=e[i].v]>d[x]+e[i].w){
d[v]=d[x]+e[i].w,pred[v]=x,pos[v]=i;
if(!in[v])in[q[++tl]=v]=1;
}
}
}
if(d[t]==0x3f3f3f3f)return 0;
int p=t;
F+=d[t];
while(p^s)--e[pos[p]].c,++e[pos[p]^1].c,p=pred[p];
return 1;
}
}
int main(){
n=read(),m=read();
mcmf::init();
for(ri i=1;i<=n;++i){
up[i]=n,down[i]=1;
for(ri j=1;j<=n;++j)mcmf::add(mcmf::s,i,1,j*j-(j-1)*(j-1));
mcmf::add(i+n,mcmf::t,1,0);
}
for(ri t,l,r,v,tt=1;tt<=m;++tt){
t=read(),l=read(),r=read(),v=read();
if(t==1)for(ri i=l;i<=r;++i)down[i]=max(down[i],v);
else for(ri i=l;i<=r;++i)up[i]=min(up[i],v);
}
for(ri i=1;i<=n;++i){
if(up[i]<down[i])return puts("-1"),0;
for(ri j=down[i];j<=up[i];++j)mcmf::add(j,i+n,1,0);
}
while(mcmf::bfs());
cout<<mcmf::F;
return 0;
}
G题
传送门
咕咕咕
Codeforces 863 简要题解的更多相关文章
- Codeforces 381 简要题解
做的太糟糕了...第一题看成两人都取最优策略,写了个n^2的dp,还好pre-test良心(感觉TC和CF的pretest还是很靠谱的),让我反复过不去,仔细看题原来是取两边最大的啊!!!前30分钟就 ...
- Codeforces 1120 简要题解
文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述:给你一个mmm个数的数列,现在规定把一个数列的1,2,...,k1,2,...,k1,2,...,k分成第一组,把k+1, ...
- Codeforces 1098 简要题解
文章目录 前言 A题 B题 C题 D题 E题 传送门 前言 没错因为蒟蒻太菜了这场的最后一道题也咕掉了,只有AAA至EEE的题解233 A题 传送门 题意简述:给出一棵带点权的树,根节点深度为111, ...
- Codeforces 1110 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...
- Codeforces 380 简要题解
ABC见上一篇. 感觉这场比赛很有数学气息. D: 显然必须要贴着之前的人坐下. 首先考虑没有限制的方案数.就是2n - 1(我们把1固定,其他的都只有两种方案,放完后长度为n) 我们发现对于一个限制 ...
- Codeforces 845 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意:2n2n2n个人下棋,分为两个阵营,每个阵营nnn个人,每个人有一个积分,积分高的能赢积分低的,问如果你可以随意选人,然 ...
- Codeforces 1065 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 GGG题略难,膜了一波zhouyuyang{\color{red} zhouyuyang}zhouyuyang巨佬的代码. 其余都挺清真的. ...
- Codeforces 888 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意简述:给一个数列,问有多少个峰值点(同时比两边都大/小的点) 思路:按照题意模拟. 代码: #include<bit ...
- Codeforces 884 简要题解
文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述: 一个人要完成一件事总共需要ttt秒,现在有nnn天,每天有aia_iai不能做事,问他可以在第几天做完. 思路:按照题 ...
随机推荐
- socket.io诡异的问题
在socket.io客户端连接的时候,如果传入的query包含“sid”这个键时会报错,不知道具体原因.
- FireDac 同时连接SQLserver2000时出现 Connection is busy with results for another command
First chance exception at $763FC632. Exception class EMSSQLNativeException with message '[FireDAC][P ...
- CountDownLatch原理及使用场景
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量.每当一个线程完成了自己的任务后,计数器的值就会减1.当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁 上 ...
- struts2.5入门
引用链接:https://www.cnblogs.com/qulianqing/p/6627746.html
- Dear Menuhin
2017-11-26 Sa Nov 11:05 AM @ HOME, TOSBE Nicole assigned us a composition about the Thanksgiving day ...
- layui表格点击排序按钮后,表格绑定事件失效解决方法
最近项目使用layui较为频繁,遇到了一个麻烦的问题,网上搜索也没有看到同类型的问题,故此记下来. 需求是点击上图右侧表格中某一个单元格,会触发点击事件如下代码: $("table>t ...
- 兼容的获取样式的函数getStyle()
想要得到某个元素的某个样式属性,可以用: <div id="div01" style="color:red">123</div> var ...
- mybatis调用存储过程并且有多个返回output值
mapperxml配置 配置时需要注意 parameterMap在mybatis3.2.6版本已经不再用了,而是使用 parameterType <select id="callget ...
- HTTP请求方式
HTTP协议中请求的8中方法 OPTIONS获取服务器支持的HTTP请求方法: HEAD跟get很像,但是不返回响应体信息,用于检查对象是否存在,并获取包含在响应消息头中的信息. GET向特定的资源发 ...
- List接口特有功能
List 有序的 有整数索引 允许重复使用 特有功能: void add(int index, E element) //指定位置添加元素 E get()int index) ...