Codeforces 837 简要题解
传送门
并没有找到难度评级但感觉是div3div3div3场。
A题
题意:一个单词的价值是里面大写字母的个数,一篇文章的价值是里面所有单词的价值的最大值。
求一篇文章的价值。
思路:按照题意模拟。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
char s[205];
int main(){
int t,ans=0;
cin>>t;
while(~scanf("%s",s)){
int cnt=0;
for(ri i=0,up=strlen(s);i<up;++i){
if(s[i]>='A'&&s[i]<='Z')++cnt;
}
ans=max(ans,cnt);
}
cout<<ans;
return 0;
}
B题
传送门
题意:给你一个n∗mn*mn∗m的三色方阵,问是否满足这个方阵被三种颜色均分成三个长宽都相等的子方阵。
思路:按照题意模拟。
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=105;
const int rlen=1<<18|1;
inline char gc(){
return getchar();
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 n,m;
char s[105][105];
inline void check1(){
char tmp=s[1][1];
if(s[1][1]==s[n/3+1][1]||s[n/3+1][1]==s[n/3*2+1][1]||s[1][1]==s[n/3*2+1][1])return;
bool f=1;
for(ri i=1;i<=n/3;++i){
for(ri j=1;j<=m;++j){
if(s[i][j]!=tmp){
f=0;
break;
}
}
if(!f)break;
}
if(!f)return;
tmp=s[n/3+1][1];
for(ri i=n/3+1;i<=n/3*2;++i){
for(ri j=1;j<=m;++j){
if(s[i][j]!=tmp){
f=0;
break;
}
}
if(!f)break;
}
if(!f)return;
tmp=s[n/3*2+1][1];
for(ri i=n/3*2+1;i<=n;++i){
for(ri j=1;j<=m;++j){
if(s[i][j]!=tmp){
f=0;
break;
}
}
if(!f)break;
}
if(!f)return;
puts("YES");
exit(0);
}
inline void check2(){
char tmp=s[1][1];
if(s[1][1]==s[1][m/3+1]||s[1][m/3+1]==s[1][m/3*2+1]||s[1][1]==s[1][m/3*2+1])return;
bool f=1;
for(ri i=1;i<=n;++i){
for(ri j=1;j<=m/3;++j){
if(s[i][j]!=tmp){
f=0;
break;
}
}
if(!f)break;
}
if(!f)return;
tmp=s[1][m/3+1];
for(ri i=1;i<=n;++i){
for(ri j=m/3+1;j<=m/3*2;++j){
if(s[i][j]!=tmp){
f=0;
break;
}
}
if(!f)break;
}
if(!f)return;
tmp=s[1][m/3*2+1];
for(ri i=1;i<=n;++i){
for(ri j=m/3*2+1;j<=m;++j){
if(s[i][j]!=tmp){
f=0;
break;
}
}
if(!f)break;
}
if(!f)return;
puts("YES");
exit(0);
}
int main(){
n=read(),m=read();
for(ri i=1;i<=n;++i)scanf("%s",s[i]+1);
if(n%3&&m%3)return puts("NO"),0;
if(!(n%3))check1();
if(!(m%3))check2();
puts("NO");
return 0;
}
C题
传送门
题意:你有一个a∗ba*ba∗b的方格和nnn个长宽为xi,yix_i,y_ixi,yi的印章,要求你放两个印章上去,它们不能相交且印章覆盖总面积最大,每个印章可以旋转90°90\degree90°。
思路:按照题意模拟。
代码:
#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;
const int N=105;
int n,a,b,tot=0,ans=0;
struct Node{int a,b,id;}A[N<<1];
inline void update(const Node&A,const Node&B){
if(A.id==B.id)return;
if(A.a>a||B.a>a||A.b>b||B.b>b)return;
if(A.a+B.a<=a||A.b+B.b<=b)ans=max(ans,A.a*A.b+B.a*B.b);
}
int main(){
n=read(),a=read(),b=read();
for(ri x,y,i=1;i<=n;++i)x=read(),y=read(),A[++tot]=(Node){x,y,i},A[++tot]=(Node){y,x,i};
for(ri i=1;i<=tot;++i)for(ri j=1;j<=tot;++j)update(A[i],A[j]);
cout<<ans;
return 0;
}
D题
传送门
题意:规定一个数的价值是其后缀0个数,现在要求你从nnn个数中选kkk个出来乘起来,问乘积的价值的最大值。n≤200,ai≤1e18n\le200,a_i\le1e18n≤200,ai≤1e18
思路:
显然只用关心222和555的个数。
考虑dpdpdp,定义状态fi,j,kf_{i,j,k}fi,j,k表示前iii个选了jjj个,555的个数为kkk时222的个数的最大值。
然后随便转移一下最后取一个最值就完了。
代码:
#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++;
}
typedef long long ll;
inline ll read(){
ll 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;
const int N=205,K=7005;
int n,k,f[2][N][K],tmp=0;
inline pii solve(ll x){
int c1=0,c2=0;
while(x==x/2*2)++c1,x/=2;
while(x==x/5*5)++c2,x/=5;
return pii(c1,c2);
}
int main(){
n=read(),k=read();
int sum=0;
pii a;
memset(f[tmp],-1,sizeof(f[tmp]));
f[tmp][0][0]=0;
for(ri tt=1;tt<=n;++tt){
ll x=read();
a=solve(x);
sum+=a.se;
tmp^=1;
memcpy(f[tmp],f[tmp^1],sizeof(f[tmp]));
for(ri j=1;j<=k;++j)for(ri i=a.se;i<=sum;++i)if(~f[tmp^1][j-1][i-a.se])f[tmp][j][i]=max(f[tmp][j][i],f[tmp^1][j-1][i-a.se]+a.fi);
}
int ans=0;
for(ri j=0;j<=k;++j)for(ri i=0;i<=sum;++i)ans=max(ans,min(i,f[tmp][j][i]));
cout<<ans;
return 0;
}
E题
传送门
题意:有一个函数f(a,b):f(a,b):f(a,b):
f(a,0)=0,f(a,b>0)=f(a,b−gcd(a,b))+1f(a,0)=0,f(a,b>0)=f(a,b-gcd(a,b))+1f(a,0)=0,f(a,b>0)=f(a,b−gcd(a,b))+1
问f(x,y)f(x,y)f(x,y)等于多少a,b≤1e12a,b\le1e12a,b≤1e12
思路:
发现对于a,b,g=gcd(a,b)a,b,g=gcd(a,b)a,b,g=gcd(a,b),f(a,b)=f(ag,bg)f(a,b)=f(\frac ag,\frac bg)f(a,b)=f(ga,gb)
于是我们模拟一下这个过程,每次求出当前的bbb减几之后会跟当前的aaa的gcdgcdgcd大于111即可。
实现可以每次暴力求出aaa的所有约数来判断。
代码:
#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++;
}
typedef long long ll;
inline ll read(){
ll ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
ll x,y;
vector<ll>divv;
inline void solve(ll x){
if(x==1){divv.push_back(1);return;}
divv.clear();
for(ri i=2;(ll)i*i<=x;++i){
if(x!=x/i*i)continue;
divv.push_back(i);
if((ll)i*i!=x)divv.push_back(x/i);
}
divv.push_back(x);
sort(divv.begin(),divv.end());
}
int main(){
x=read(),y=read();
ll ans=0;
solve(x);
while(y>=divv[0]){
if(x==1)break;
solve(x);
ll rs=divv[0],tim=y-y/rs*rs;
for(ri i=1,up=divv.size();i<up;++i){
if(divv[i]>y)break;
if(y-y/divv[i]*divv[i]<=tim)rs=divv[i],tim=y-y/rs*rs;
}
ans+=tim,y/=rs,x/=rs;
solve(x);
}
cout<<ans+y;
return 0;
}
F题
传送门
题意:
定义函数f(a),a为数列=数列b,bi=∑j=1iaif(a),a为数列=数列b,b_i=\sum_{j=1}^i a_if(a),a为数列=数列b,bi=∑j=1iai
现在有一个初始数列aaa和一个数kkk,问对这个数列调用几次fff函数之后序列中会存在一个数不小于kkk,∣a∣≤200000,k≤1e18|a|\le200000,k\le1e18∣a∣≤200000,k≤1e18
思路:
显然特判掉次数为0,10,10,1的情况然后二分答案,checkcheckcheck的话直接看最后一个数是否小于kkk即可。
手推一波公式会发现初始数列中每个数对于要求值贡献的系数是组合数,因此我们暴力加就是了,注意可能会爆longlonglong longlonglong。
代码:
#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++;
}
typedef long long ll;
inline ll read(){
ll 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=2e5+5;
int n;
ll k,a[N];
inline bool check(ll tim){
long double sum=0,fac=1;
for(ri i=1;i<=n;++i){
if(i^1)fac=fac*(i+tim-2);
if(i^1)fac/=(i-1);
if(fac>k||fac<0)fac=k;
if(fac*a[n-i+1]<0)return 1;
sum+=fac*a[n-i+1];
if(sum>=k||sum<0)return 1;
}
return 0;
}
int main(){
n=read(),k=read();
for(ri i=1;i<=n;++i){
a[i]=read();
if(a[i]>=k)return puts("0"),0;
}
ll sum=0;
for(ri i=1;i<=n;++i)sum+=a[i];
if(sum>=k)return puts("1"),0;
ll l=2,r=k,res=k;
while(l<=r){
ll mid=l+r>>1;
if(check(mid))r=mid-1,res=mid;
else l=mid+1;
}
cout<<res;
return 0;
}
G题
传送门
题意:现在有nnn个分段函数,fi(x)f_i(x)fi(x)有666个参数x1,x2,y1,a,b,y2x_1,x_2,y_1,a,b,y_2x1,x2,y1,a,b,y2
f(x)=y1,0≤x≤x1f(x)=y1,0\le x\le x_1f(x)=y1,0≤x≤x1
f(x)=ax+b,x1<x≤x2f(x)=ax+b,x_1<x\le x_2f(x)=ax+b,x1<x≤x2
f(x)=y2,x2<xf(x)=y2,x_2<xf(x)=y2,x2<x
现在有mmm次询问,每次给出l,r,xl,r,xl,r,x,求∑i=lrfi(x)\sum_{i=l}^rf_i(x)∑i=lrfi(x),强制在线。
思路:显然需要维护一个∑i=1kfi(x)\sum_{i=1}^kf_i(x)∑i=1kfi(x)
考虑到将f(x)f(x)f(x)稍加改动:
f(x)=0x+y1,0≤x≤x1f(x)=0x+y1,0\le x\le x_1f(x)=0x+y1,0≤x≤x1
f(x)=ax+b,x1<x≤x2f(x)=ax+b,x_1<x\le x_2f(x)=ax+b,x1<x≤x2
f(x)=0x+y2,x2<xf(x)=0x+y2,x_2<xf(x)=0x+y2,x2<x
这启发我们最后答案等于Ax+BAx+BAx+B,因此我们只需要维护A,BA,BA,B的和即可。
这个可以用主席树实现。
代码:
#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 long long ll;
const int N=75005,M=N*120;
int rt[N],n;
struct data{
ll a,b;
data(ll a=0,ll b=0):a(a),b(b){}
friend inline data operator+(const data&a,const data&b){return data(a.a+b.a,a.b+b.b);}
friend inline data operator-(const data&a,const data&b){return data(a.a-b.a,a.b-b.b);}
};
namespace SGT{
#define lc (son[p][0])
#define rc (son[p][1])
#define mid (l+r>>1)
data sum[M];
int son[M][2],tot=0;
inline void update(int&p,int o,int l,int r,int ql,int qr,data v){
p=++tot,lc=son[o][0],rc=son[o][1],sum[p]=sum[o];
if(ql<=l&&r<=qr){sum[p]=sum[p]+v;return;}
if(qr<=mid)update(lc,son[o][0],l,mid,ql,qr,v);
else if(ql>mid)update(rc,son[o][1],mid+1,r,ql,qr,v);
else update(lc,son[o][0],l,mid,ql,mid,v),update(rc,son[o][1],mid+1,r,mid+1,qr,v);
}
inline data query(int&p,int l,int r,int k){return !p?data(0,0):(l==r?sum[p]:sum[p]+(k<=mid?query(lc,l,mid,k):query(rc,mid+1,r,k)));}
#undef lc
#undef rc
#undef mid
}
int main(){
n=read();
int lim=200001;
for(ri i=1,x1,x2,y1,a,b,y2;i<=n;++i){
x1=read(),x2=read(),y1=read(),a=read(),b=read(),y2=read();
rt[i]=rt[i-1];
SGT::update(rt[i],rt[i],0,lim,0,x1,data(0,y1));
SGT::update(rt[i],rt[i],0,lim,x1+1,x2,data(a,b));
SGT::update(rt[i],rt[i],0,lim,x2+1,lim,data(0,y2));
}
ll lastans=0;
data tmp;
for(ri l,r,x,tt=read();tt;--tt){
l=read(),r=read(),x=(lastans+read())%1000000000;
tmp=SGT::query(rt[r],0,lim,min(x,lim))-SGT::query(rt[l-1],0,lim,min(x,lim));
cout<<(lastans=tmp.a*x+tmp.b)<<'\n';
}
return 0;
}
Codeforces 837 简要题解的更多相关文章
- Codeforces 863 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...
- 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 ...
随机推荐
- Linux命令:pushd
语法 pushd [-n] [+N | -N | dir] 更改新目录并(或)压栈,或者把栈里的某个目录推到栈顶. 说明 pushd dir # 切换到目标目录dir,并将dir压栈. pushd # ...
- 获得随机N位数不重复数字
1, 总结下:每个Random实例里面有一个原子性的种子变量用来记录当前的种子的值,当要生成新的随机数时候要根据当前种子计算新的种子并更新回原子变量.多线程下使用单个Random实例生成随机数时候,多 ...
- 使用hexo在GitHub上无法上传博客
原以为是秘钥或者其他错误,后来发现是邮箱设置的问题 在GitHub的你账号网页上右上角,个人的登录退出的位置,找到setting: setting->emails->Keep my ema ...
- CSS 背景图像 背景图片定位
背景图片定位 background-position属性可以给背景图片定位. background-position属性有两个值,第一个值是水平位置,第二个值是垂直位置.这两个值可以使用百分比来表示( ...
- MySQL 自带4个默认数据库
默认数据库分类: information_schema performance_schema mysql test informance_schema 保存了MySQl服务所有数据库的信息. 具体My ...
- react学习2
props,state与render函数的关系 react,父组件的state中的变量改变,则相应的render函数也会执行,返回新的视图,同时父组件的子组件通过props获取父组件的state的变量 ...
- C#分割字符串并统计重复出现的次数
static void Main(string[] args) { string ss = "12345678904682qwertyuioplkjhgfdsazxcvbnmmlpokuhy ...
- 基于django的博客系统
这是前段代码 达到的效果并不是太好,但我还是要发出来,有更好的建议可以和我讨论 后台还算可以 添加了分类和文章两个功能,还在优化,敬请期待....
- MySql中三种注释写法
需要特别注意 -- 这种注释后面要加一个空格 #DELETE FROM SeatInformation /*DELETE FROM SeatInformation */ -- DELETE FR ...
- TZOJ 2569 Wooden Fence(凸包求周长)
描述 Did you ever wonder what happens to your money when you deposit them to a bank account? All banks ...