【CodeChef】August Challenge 2019 Div2 解题报告
\(T1\):Football(点此看题面)
大致题意: 求\(max(20a_i-10b_i,0)\)。
送分题不解释。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 150
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n,a[N+5],b[N+5];
int main()
{
RI Tt,i,x,y,ans;scanf("%d",&Tt);W(Tt--)
{
for(scanf("%d",&n),ans=0,i=1;i<=n;++i) scanf("%d",a+i);
for(i=1;i<=n;++i) scanf("%d",b+i),Gmax(ans,20*a[i]-10*b[i]);//统计答案
printf("%d\n",ans);
}return 0;
}
\(T2\):Distribute Apples(点此看题面)
大致题意: 有两种分苹果方法,一种把\(n\)个苹果平均分到\(k\)个盒子中,一种每次在一个盒子中放\(k\)个苹果放\(\frac nk\)次,判断两种放法结果是否一样。
考虑苹果总数是一样的,因此只要第二种方法能做到平均分配,结果就是一样的。
而第二种方法做到平均分配,就说明\(k|\frac nk\)。
判一下即可。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 150
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
long long n,k;
int main()
{
RI Tt,i,x,y,ans;scanf("%d",&Tt);W(Tt--)
scanf("%lld%lld",&n,&k),puts((n%k||(n/k)%k)?"YES":"NO");//判断k|(n/k)
return 0;
}
\(T3\):Dilemma (点此看题面)
大致题意: 给你一个\(01\)序列,每次能把一个为\(1\)的位置变成\(-1\),将其相邻的\(0\)变成\(1\)、\(1\)变成\(0\)。问是否能把所有位置变成\(-1\)。
结论题?
首先,可以发现,如果把若干个连续\(0\)换成一个\(0\),答案不变,如\(101\)和\(1001\)。
其次,可以发现,若只有长度为偶数的连续\(1\)的序列,是不可以的,如\(1111\),\(01101111110\)。但只要有一个长度为奇数的连续\(1\)的序列,就可以了,如\(111011\)。也就是说,除去长度为偶数的连续\(1\)的序列,答案不变。
也就是说,我们只需考虑长度为奇数的连续\(1\)的序列。
然后画图找找规律,就可以发现当有奇数个长度为奇数的连续\(1\)的序列时可以,否则不可以。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n;char s[N+5];
int main()
{
RI Tt,i,t=0,res=0;scanf("%d",&Tt);W(Tt--)
{
for(scanf("%s",s),n=strlen(s),t=res=i=0;i^n;++i)
s[i]&1?(t^=1):(res^=t,t=0);puts(res^t?"WIN":"LOSE");//t统计当前连续1序列的奇偶性,res统计长度为奇数的连续1的序列的个数的奇偶性
}return 0;
}
\(T4\):Zombie and the Caves(点此看题面)
大致题意: 给你个数组\(C\)以及一个空序列,对于每个\(i\),把序列中第\(i-C_i\sim i+C_i\)个位置都加上\(1\),再给你一个序列,问两个序列中的数是否能一一匹配。
我们先差分求出这个序列,然后排序比较两个序列即可。
这里我用了桶排。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
using namespace std;
int n,s[N+5],p[N+5];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
int main()
{
RI Tt,i,x,f;F.read(Tt);W(Tt--)
{
for(F.read(n),i=1;i<=n;++i) s[i]=p[i]=0;//清空
for(i=1;i<=n;++i) F.read(x),++s[max(i-x,1)],--s[min(i+x,n)+1];//差分
for(i=1;i<=n;++i) (s[i]+=s[i-1])<=n&&++p[s[i]];//求出序列并存入桶中
for(f=i=1;i<=n;++i) F.read(x),(x>n||!p[x]--)&&(f=0);puts(f?"YES":"NO");//判断是否可以一一匹配
}return 0;
}
\(T5\):Guddu and his Mother(点此看题面)
大致题意: 给你一个序列,求有多少组\((i,j,k)\)满足\(xor_{x=i}^{j-1}a_x=xor_{x=j}^ka_x\)。
首先容易发现,对于一组\((i,k)\),若其满足\(xor_{x=i}^ka_x=0\),则对于满足\(i<j\le k\)的任意一组\((i,j,k)\)都是一组合法解,即有\(k-i\)组合法解。
若我们记\(s_i=xor_{x=1}^ia_x\),就相当于\(s_{i-1}\ xor\ s_k=0\),即\(s_{i-1}=s_k\)时,有\(k-i\)组合法解。
也就是当\(s_i=s_k\)时,有\(k-i-1=(k-1)-i\)组合法解。
所以我们开两个\(map\),\(p_x\)表示之前所有满足\(s_i=x\)的\(i\)的和,\(g_x\)表示之前满足\(s_i=x\)的\(i\)的个数。
那么我们枚举\(i\),就可以更新\(ans\)加上\(g_{s_i}(i-1)-p_{s_i}\)。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define LL long long
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
using namespace std;
int n,s[N+5];map<int,LL> p,g;
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
int main()
{
RI Tt,i,x;LL ans;F.read(Tt);W(Tt--)
{
ans=0,p.clear(),g.clear(),p[0]=0,g[0]=1;//清空
for(F.read(n),i=1;i<=n;++i) F.read(x),//读入
s[i]=s[i-1]^x,ans+=1LL*g[s[i]]*(i-1)-p[s[i]],p[s[i]]+=i,++g[s[i]];//统计前缀和,更新答案,更新map
printf("%lld\n",ans);//输出答案
}return 0;
}
\(T6\):Encoding(点此看题面)
大致题意: 设\(F(x)\)为\(x\)十进制数位中每段连续相同数字只保留最高位、其余位替换为\(0\)后的值,求\(\sum_{i=l}^rF(i)\)。
显然数位\(DP\)。
我们设\(f_{x,lst}\)和\(g_{x,lst}\)分别表示右数第\(x\)位、上一个数为\(lst\)时的答案和情况数。
考虑记忆化搜索。
对于答案,转移时先将后继状态的\(f\)求和,然后若枚举到这一位的值\(y\)不等于\(lst\),就将答案加上后继状态的\(g\)乘\(y*10^x\)。
对于情况数,直接将后继状态的\(g\)求和即可。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define X 1000000007
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
using namespace std;
int nl,nr;char L[N+5],R[N+5];
class DigitalDP
{
private:
#define Pr pair<int,int>
#define mp make_pair
#define fir first
#define sec second
int v[N+5],tn[N+5],f[N+5][10],g[N+5][10];
I Pr DP(CI x,CI lst,CI p)//数位DP
{
RI i,lim=p?v[x]:9;Pr t,k=mp(0,0);
if(!x) return mp(0,1);if(!p&&~f[x][lst]) return mp(f[x][lst],g[x][lst]);//若求过答案,直接返回
for(i=0;i<=lim;++i) t=DP(x-1,i,p&&(i==lim)),//枚举这一位填的数,处理后继状态
Inc(k.fir,t.fir),Inc(k.sec,t.sec),i^lst&&(k.fir=(1LL*tn[x]*i%X*t.sec+k.fir)%X);//统计答案和情况数
return f[x][lst]=k.fir,g[x][lst]=k.sec,k;//记忆化,返回答案
}
public:
I DigitalDP() {RI i;for(tn[1]=1,i=2;i<=N;++i) tn[i]=10LL*tn[i-1]%X;}//初始化10的幂
I int GetAns(CI x,char *s)
{
RI i,ans=0;Pr t;for(i=x;i;--i) v[i]=s[x-i]&15;memset(f,-1,sizeof(f));//清空
for(i=0;i<=v[x];++i) t=DP(x-1,i,i==v[x]),ans=(1LL*tn[x]*i%X*t.sec+t.fir+ans)%X;//枚举最高位,这个写法有点蠢啊
return ans;
}
}D;
int main()
{
RI Tt,p;scanf("%d",&Tt);W(Tt--)
{
scanf("%d%s%d%s",&nl,L,&nr,R);p=nl-1;W(L[p]=='0') L[p--]='9';--L[p];//将L-1差分
printf("%d\n",(D.GetAns(nr,R)-D.GetAns(nl,L)+X)%X);//求答案
}return 0;
}
\(T7\):Chef and Gordon Ramsay(点此看题面)
大致题意: 求有多少对\((x,y,z)\)满足\(y\)在\(x\)和\(z\)树上最短路径上,且满足给定的相对大小。
考虑一下线段树合并+大分类讨论。
我们先线段树合并,用值域线段树存下每个子树内的所有值。
然后,枚举\(y\),并对\(y\)从大到小的相对排名,以及路径完全在子树内还是部分在子树外,分类讨论:
- 若\(y\)相对排名为\(1\),求出子树内大于\(y\)的数的个数乘子树外大于\(y\)的数的个数(子树外的可以差分),并枚举子节点加上该儿子的子树内大于\(y\)的数的个数乘其他儿子子树内大于\(y\)的数的个数(其他儿子的可以差分)除以\(2\)。
- 若\(y\)相对排名为\(2\),求出子树内大于\(y\)的数的个数乘子树外小于\(y\)的数的个数加上求出子树内小于\(y\)的数的个数乘子树外大于\(y\)的数的个数,并枚举子节点加上该儿子的子树内小于\(y\)的数的个数乘其他儿子子树内大于\(y\)的数的个数。
- 若\(y\)相对排名为\(3\),与相对排名为\(1\)类似,略。
注意卡常,有些用的很多次的值不要每次都到线段树上去查询,可以直接存下来。
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define LN 20
#define LL long long
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
using namespace std;
int n,ee,lnk[N+5],Sz[N+5],p[4];LL ans;struct edge {int to,nxt;}e[N<<1];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
template<int SZ,int PS> class SegmentTree//线段树
{
private:
#define LT l,mid,O[rt].S[0]
#define RT mid+1,r,O[rt].S[1]
#define PU(x) (O[x].V=O[O[x].S[0]].V+O[O[x].S[1]].V)
int n,Nt,Rt[SZ+5];struct node {int V,S[2];}O[PS+5];
I void Ins(CI v,CI l,CI r,int& rt)//单点修改
{
if(!rt&&(rt=++Nt,O[rt].S[0]=O[rt].S[1]=0),l==r) return (void)(O[rt].V=1);
RI mid=l+r>>1;v<=mid?Ins(v,LT):Ins(v,RT),PU(rt);
}
I int Qry(CI x,CI y,CI l,CI r,CI rt)//区间求和
{
if(!rt) return 0;if(x<=l&&r<=y) return O[rt].V;RI mid=l+r>>1;
return (x<=mid?Qry(x,y,LT):0)+(y>mid?Qry(x,y,RT):0);
}
I int Merge(CI l,CI r,CI x,CI y)//线段树合并
{
if(!x||!y) return x+y;RI rt=++Nt;if(l==r) return (O[rt].V=O[x].V+O[y].V);RI mid=l+r>>1;
O[rt].S[0]=Merge(l,mid,O[x].S[0],O[y].S[0]),O[rt].S[1]=Merge(mid+1,r,O[x].S[1],O[y].S[1]);
return PU(rt),rt;
}
public:
I void Init(CI _n) {Nt=0,n=_n;for(RI i=1;i<=n;++i) Rt[i]=0;}
I void Ins(CI id,CI v) {Ins(v,1,n,Rt[id]);}
I int Qry(CI id,CI l,CI r) {return Qry(l,r,1,n,Rt[id]);}
I void Merge(CI x,CI y) {Rt[x]=Merge(1,n,Rt[x],Rt[y]);}
};SegmentTree<N,N*LN<<1> S;
I void dfs(CI x,CI lst=0)
{
RI i;for(Sz[x]=1,S.Ins(x,x),i=lnk[x];i;i=e[i].nxt)//处理子树,合并子树线段树
e[i].to^lst&&(dfs(e[i].to,x),Sz[x]+=Sz[e[i].to],S.Merge(x,e[i].to),0);
LL res=0;RI t,t1=S.Qry(x,1,x-1),t2=Sz[x]-t1-1;
if(p[2]==1)//若y相对排名为1
{
ans+=1LL*(n-x-t2)*t2;//部分在子树外
for(RI i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&//完全在子树内
(t=S.Qry(e[i].to,x+1,n),res+=1LL*(t2-t)*t);
}
else if(p[2]==2)//若y相对排名为2
{
ans+=1LL*(n-x-t2)*t1+1LL*(x-1-t1)*t2;//部分在子树外
for(RI i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&//完全在子树内
(t=S.Qry(e[i].to,x+1,n),res+=1LL*(t2-t)*(Sz[e[i].to]-t));
}
else//若y相对排名为3
{
ans+=1LL*(x-1-t1)*t1;//部分在子树外
for(RI i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&//完全在子树内
(t=S.Qry(e[i].to,1,x-1),res+=1LL*(t1-t)*t);
}ans+=res>>(p[2]!=2);
}
int main()
{
RI Tt,i,x,y;F.read(Tt);W(Tt--)
{
for(F.read(n),S.Init(n),ee=0,i=1;i<=n;++i) lnk[i]=0;//清空
for(i=1;i<=3;++i) F.read(p[i]);for(i=1;i^n;++i) F.read(x,y),add(x,y),add(y,x);//读入建边
ans=0,dfs(1),printf("%lld\n",ans);//输出答案
}return 0;
}
【CodeChef】August Challenge 2019 Div2 解题报告的更多相关文章
- 【CodeChef】December Challenge 2019 Div1 解题报告
点此进入比赛 这次比赛本来想好好打的,但不幸的是,这周先是要认真复习准备月考,考完又是发烧在床上躺了一个周末,所以最终没能打完. 我还是好弱啊. \(T1\):Binary XOR(点此看题面) 大致 ...
- Codechef August Challenge 2019 Division 2
Preface 老年菜鸡终于开始打CC了,由于他太弱了所以只能打Div2 因为台风的原因challenge并没有写,所以水了个Rank7 A Football SB模拟题不解释 #include< ...
- Codechef August Challenge 2019 Chef and Gordon Ramsay
[传送门] 题目即求所有的三元组,相对大小关系同 $p_1,p_2,p_3$. 题解说都很清楚,这里写一下过程整理一下思路. 如果我们枚举中间这个元素,那么就是统计子树内外有多少个大于这个数和小于这个 ...
- Codechef April Challenge 2019 游记
Codechef April Challenge 2019 游记 Subtree Removal 题目大意: 一棵\(n(n\le10^5)\)个结点的有根树,每个结点有一个权值\(w_i(|w_i\ ...
- Codechef September Challenge 2019 Division 2
Preface 这确实应该是我打过的比较水的CC了(其实就打过两场) 但由于我太弱了打的都是Div2,所以会认为上一场更简单,其实上一场Div的数据结构是真的毒 好了废话不多说快速地讲一下 A Eas ...
- codeforce 192 div2解题报告
今天大家一起做的div2,怎么说呢,前三题有点坑,好多特判.... A. Cakeminator 题目的意思是说,让你吃掉cake,并且是一行或者一列下去,但是必须没有草莓的存在.这道题目,就是判断一 ...
- CodeChef April Challenge 2019题解
传送门 \(Maximum\ Remaining\) 对于两个数\(a,b\),如果\(a=b\)没贡献,所以不妨假设\(a<b\),有\(a\%b=a\),而\(b\%a<a\).综上, ...
- Codeforces #263 div2 解题报告
比赛链接:http://codeforces.com/contest/462 这次比赛的时候,刚刚注冊的时候非常想好好的做一下,可是网上喝了个小酒之后.也就迷迷糊糊地看了题目,做了几题.一觉醒来发现r ...
- Crypto Challenge Set 1解题报告
1.Convert hex to base64 题意:给出一个hex编码过的字符串,将它进行base64加密 解题关键:直接利用base64库函数实现 import base64 str1=" ...
随机推荐
- 设计模式-State(行为模式)-很好的实现了对象的状态逻辑与动作实现的分类,状态逻辑在State的派生类实现,动作可以放在Context类中实现。
以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Context.h #pragma once class State; class Context { public: C ...
- console调试技巧
1.console.log() 我们经常会使用console.log来打印出某个变量的值或者某个实体对象,也可以传入多个变量参数,它会按照传入顺序进行打印: 1. 传入一个变量 const a = 1 ...
- Noip2016Day2T3 愤怒的小鸟
题目链接 problem 平面内有n个点,每次可以确定一条过原点且开口向上的抛物线,将这条抛物线上所有的点都删去.问最少需要删几次可以删掉全部的点. solution n比较小,直接状压一下.因为已经 ...
- import和from...import
目录 一.import 模块名 二.from 模块名 import 具体的功能 三.import和from...import...的异同 一般使用import和from...import...导入模块 ...
- ssh 免密码登录服务器
本机生成 ssh key ssh-keygen -t rsa -C "your_email@example.com" 上传公钥文件(假设用户为 user,服务器 ip 为 1.2. ...
- vscode常用快捷键与插件推荐
一.vscode常用快捷键 1.新建文件:chtr+n 2.新开窗口:ctrl+shift+n 3.分屏:ctrl+1/2/3 4.切换文件:alt+1/2/3或ctrl+tab 5.关闭当前窗口: ...
- 1+x 证书 Web 前端开发初级理论考试(试卷8 )
Web前端开发初级模拟测试卷(三) 共55道题 总分:200分 形考总分:0分 一.单选题共30题,60分 1.实现向右的红色三角形,样式实现正确的是( ) A <div class=" ...
- ActiveMQ是什么,为什么使用MQ
是基于 Java 中的 JMS 消息服务规范实现的一个消息中间件. 1.系统解耦 采用中间件之后,就可以完美解决上述中因为耦合可能导致的问题.系统 A 不用去 关心下层服务调用方的问题. 2. 异步调 ...
- 【转】linux下使用sqlplus执行包含语句块的sql文件,运行时会不断显示行号,而在plsqldev中能执行
一.数据库:Oracle数据库 二.sql文件内容: --创建函数 CREATE OR REPLACE function fun_createuid1 return varchar2 is Resul ...
- Java内功心法,Set集合的详解
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...