文章目录

传送门

A题

传送门

题意简述:给一个数列,问有多少个峰值点(同时比两边都大/小的点)


思路:按照题意模拟。

代码:

#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=1005;
int n,a[N];
int main(){
	n=read();
	int cnt=0;
	for(ri i=1;i<=n;++i){
		a[i]=read();
	}
	for(ri i=2;i<n;++i){
		if(a[i]>a[i-1]&&a[i]>a[i+1])++cnt;
		if(a[i]<a[i-1]&&a[i]<a[i+1])++cnt;
	}
	cout<<cnt;
	return 0;
}

B题

传送门

题意简述:有一个机器人按照UDLRUDLRUDLR四种指令上下左右移动,有一些指令可能是错的,机器人如果只按照正确的指令走最后会回到原点,问最多有多少个指令是正确的。


思路:显然对于正确的指令L,RL,RL,R个数相等,U,DU,DU,D个数相等。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
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;
}
const int N=105;
int n;
char s[N];
int main(){
	n=read();
	int cnt1=0,cnt2=0,cnt3=0,cnt4=0;
	scanf("%s",s+1);
	for(ri i=1;i<=n;++i){
		if(s[i]=='L')++cnt1;
		if(s[i]=='R')++cnt2;
		if(s[i]=='U')++cnt3;
		if(s[i]=='D')++cnt4;
	}
	cout<<min(cnt1,cnt2)*2+min(cnt3,cnt4)*2;
	return 0;
}

C题

传送门

题意简述:

给一个字符串SSS,一个字符ccc为kkk好的当SSS的所有长度为kkk的子串都包含这个字符,问最小的kkk满足存在至少有一个字符是kkk好的。


思路:显然可以二分答案,然后随便checkcheckcheck一下。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
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;
}
const int N=100005;
int n,k;
char s[N];
inline bool check(const int&k){
	for(ri i=0;i<26;++i){
		bool f=1;
		int last=0;
		for(ri last=0,j=1;j<=n;++j){
			if(j-last==k)if(s[j]-'a'!=i){f=0;break;}
			if(s[j]-'a'==i)last=j;
		}
		if(f)return 1;
	}
	return 0;
}
int main(){
	scanf("%s",s+1),n=strlen(s+1);
	int l=1,r=n,ans=n;
	while(l<=r){
		int mid=l+r>>1;
		if(check(mid))r=mid-1,ans=mid;
		else l=mid+1;
	}
	cout<<ans;
	return 0;
}

D题

传送门

题意简述:给出n,kn,kn,k,问有多少nnn个数排列至少有n−kn-kn−k个位置满足ai=ia_i=iai​=i。


思路:考虑dpdpdp,fi,jf_{i,j}fi,j​表示至少有jjj个位置满足ak≠ka_k=\not kak​≠​k的iii个数排列的数量。

然后从fi,j−2/j−1/jf_{i,j-2/j-1/j}fi,j−2/j−1/j​转移过来即可。

代码:

#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;
}
typedef long long ll;
const int N=1005;
int n,k;
ll f[N][N];
int main(){
	n=read(),k=read();
	f[0][0]=1;
	for(ri i=1;i<=n;++i){
		f[i][0]=1;
		for(ri j=1;j<=k;++j){
			f[i][j]=f[i-1][j]+f[i-1][j-1]*(j-1);
			if(j>=2)f[i][j]+=f[i-1][j-2]*(i-j+1);
		}
	}
	ll ans=0;
	for(ri i=0;i<=k;++i)ans+=f[n][i];
	cout<<ans;
	return 0;
}

E题

传送门

题意简述:给出nnn个数aia_iai​和一个模数m,n≤35,ai,m≤1e9m,n\le35,a_i,m\le1e9m,n≤35,ai​,m≤1e9,每个数可以选或者不选,问选出来的数模mmm得到的最大值是多少。


思路:考虑双向搜索之后去重并排序,然后用双指针或者lowerboundlower_boundlowerb​ound查询答案。

代码:

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#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;
}
tr1::unordered_map<int,bool>vis1,vis2;
typedef long long ll;
const int N=40;
int n,mod,val[N];
vector<int>A,B;
inline void solve1(){
	int pos=1;
	vis1[0]=1,A.push_back(0);
	while(pos<=n){
		for(ri i=0,up=A.size()-1;i<=up;++i)if(!vis1[(val[pos]+A[i])%mod])vis1[(val[pos]+A[i])%mod]=1,A.push_back((val[pos]+A[i])%mod);
		if(!vis1[val[pos]])vis1[val[pos]]=1,A.push_back(val[pos]);
		pos+=2;
	}
	sort(A.begin(),A.end());
}
inline void solve2(){
	int pos=2;
	vis2[0]=1,B.push_back(0);
	while(pos<=n){
		for(ri i=0,up=B.size()-1;i<=up;++i)if(!vis2[(val[pos]+B[i])%mod])vis2[(val[pos]+B[i])%mod]=1,B.push_back((val[pos]+B[i])%mod);
		if(!vis2[val[pos]])vis2[val[pos]]=1,B.push_back(val[pos]);
		pos+=2;
	}
	sort(B.begin(),B.end());
}
int main(){
	n=read(),mod=read();
	for(ri i=1;i<=n;++i)val[i]=read()%mod;
	solve1(),solve2();
	int ans=0,N=A.size()-1,M=B.size()-1;
	for(ri i=0;i<=N;++i){
		ans=max(ans,(A[i]+B[M])%mod);
		if(A[i]+B[M]>mod-1){
			int pos=lower_bound(B.begin(),B.end(),mod-A[i]-1)-B.begin();
			while(~pos&&B[pos]>mod-A[i]-1)--pos;
			if(pos==-1)continue;
			ans=max(ans,(A[i]+B[pos])%mod);
		}
	}
	cout<<ans;
	return 0;
}

F题

传送门

题意简述:平面上有n,n≤500n,n\le500n,n≤500个点按凸多边形排列,现在让你把它们连成一棵树,有一些边不能用,边与边不能相交,问方案数。


思路:

考虑dpdpdp,fl,rf_{l,r}fl,r​表示这一段按照题意连成一棵树的方案数。

然后对于fl,rf_{l,r}fl,r​可以通过枚举一个iii,使得l,l+r,...,il,l+r,...,il,l+r,...,i这些点只有iii跟rrr连边来转移,这个时候发现i+1,i+2,..,r−1i+1,i+2,..,r-1i+1,i+2,..,r−1的连法有点窒息,于是我们再开一个数组gl,rg_{l,r}gl,r​专门处理这个转移即可。

代码:

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#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;
}
typedef long long ll;
const int N=505,mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void update(int&a,const int&b){a=add(a,b);}
int n,f[N][N],g[N][N],ans=0,Trans[N][N];
inline int trans(int x,int y){return Trans[x>n?x-n:x][y>n?y-n:y];}
inline int dfs(int l,int r);
inline int calc(int l,int r){
	if(~g[l][r])return g[l][r];
	if(l==r)return g[l][r]=trans(l-1,l)+trans(r,r+1);
	g[l][r]=0;
	update(g[l][r],dfs(l-1,r));
	update(g[l][r],dfs(l,r+1));
	for(ri i=l;i<r;++i)update(g[l][r],mul(dfs(l-1,i),dfs(i+1,r+1)));
	return g[l][r];
}
inline int dfs(int l,int r){
	if(~f[l][r])return f[l][r];
	if(l==r)return f[l][r]=1;
	if(l==r-1)return f[l][r]=trans(l,r);
	f[l][r]=dfs(l,r-1)*trans(r-1,r);
	for(ri tmp1,tmp2,tmp3,i=l;i<r-1;++i)if(trans(i,r))update(f[l][r],mul(dfs(l,i),calc(i+1,r-1)));
	return f[l][r];
}
int main(){
	n=read();
	memset(f,-1,sizeof(f)),memset(g,-1,sizeof(g));
	for(ri i=1;i<=n;++i)for(ri j=1;j<=n;++j)Trans[i][j]=read();
	cout<<dfs(1,n);
	return 0;
}

G题

传送门

题意简述:给你nnn个点的无向完全图,每个点有点权,边权为连接的两个点的点权异或值。

问这张图的最小生成树。


思路:考虑到按位贪心的正确性是显然的,于是我们用相当于在01trie01trie01trie上面走的方式进行分治,每次统计将两棵子树合并的贡献时把左子树插入一棵01trie01trie01trie,然后右子树去查询取最值即可。

代码:

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#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;
}
typedef long long ll;
const int N=2e5+5;
int n,a[N],atmp[2][N];
namespace trie{
	int son[N*30][2],rt,tot;
	inline void build(int p){son[p][0]=son[p][1]=0;}
	inline void init(){build(rt=tot=1);}
	inline void insert(int x){
		for(ri t,p=rt,i=30;~i;--i){
			if(!son[p][t=(x>>i)&1])build(son[p][t]=++tot);
			p=son[p][t];
		}
	}
	inline int query(int x){
		int ret=0;
		for(ri p=rt,t,i=30;~i;--i){
			if(son[p][t=(x>>i)&1])p=son[p][t];
			else ret|=1<<i,p=son[p][t^1];
		}
		return ret;
	}
}
inline ll solve(int l,int r,int dep){
	if(dep==-1||l>r)return 0;
	int tp[2];
	tp[0]=tp[1]=0;
	int ret=0;
	for(ri t,i=l;i<=r;++i)++tp[t=(a[i]>>dep)&1],atmp[t][tp[t]]=a[i];
	if(tp[0]&&tp[1]){
		ret=1<<(dep+1);
		trie::init();
		for(ri i=1;i<=tp[0];++i)trie::insert(atmp[0][i]);
		for(ri i=1;i<=tp[1];++i)ret=min(ret,trie::query(atmp[1][i]));
	}
	for(ri i=l;i<=l+tp[0]-1;++i)a[i]=atmp[0][i-l+1];
	for(ri i=l+tp[0];i<=r;++i)a[i]=atmp[1][i-l-tp[0]+1];
	return solve(l,l+tp[0]-1,dep-1)+ret+solve(l+tp[0],r,dep-1);
}
int main(){
	n=read();
	for(ri i=1;i<=n;++i)a[i]=read();
	cout<<solve(1,n,30);
	return 0;
}

Codeforces 888 简要题解的更多相关文章

  1. Codeforces 863 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...

  2. Codeforces 381 简要题解

    做的太糟糕了...第一题看成两人都取最优策略,写了个n^2的dp,还好pre-test良心(感觉TC和CF的pretest还是很靠谱的),让我反复过不去,仔细看题原来是取两边最大的啊!!!前30分钟就 ...

  3. Codeforces 1120 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述:给你一个mmm个数的数列,现在规定把一个数列的1,2,...,k1,2,...,k1,2,...,k分成第一组,把k+1, ...

  4. Codeforces 1098 简要题解

    文章目录 前言 A题 B题 C题 D题 E题 传送门 前言 没错因为蒟蒻太菜了这场的最后一道题也咕掉了,只有AAA至EEE的题解233 A题 传送门 题意简述:给出一棵带点权的树,根节点深度为111, ...

  5. Codeforces 1110 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...

  6. Codeforces 380 简要题解

    ABC见上一篇. 感觉这场比赛很有数学气息. D: 显然必须要贴着之前的人坐下. 首先考虑没有限制的方案数.就是2n - 1(我们把1固定,其他的都只有两种方案,放完后长度为n) 我们发现对于一个限制 ...

  7. Codeforces 845 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意:2n2n2n个人下棋,分为两个阵营,每个阵营nnn个人,每个人有一个积分,积分高的能赢积分低的,问如果你可以随意选人,然 ...

  8. Codeforces 1065 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 GGG题略难,膜了一波zhouyuyang{\color{red} zhouyuyang}zhouyuyang巨佬的代码. 其余都挺清真的. ...

  9. Codeforces 884 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述: 一个人要完成一件事总共需要ttt秒,现在有nnn天,每天有aia_iai​不能做事,问他可以在第几天做完. 思路:按照题 ...

随机推荐

  1. Tensorflow卷积神经网络[转]

    Tensorflow卷积神经网络 卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络, 在计算机视觉等领域被广泛应用. 本文将简单介绍其原理并分析Te ...

  2. BitmapData.threshold()方法

    import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Rectangle; import fl ...

  3. Suse linux enterprise 11安装时更改磁盘模式为gpt的方法

    在进行鸟哥linux基础篇学习时,在"第3.2.2 选择安装模式与开机 -inst.gpt"中,鸟哥用到的CentOS 7需要用指令修改磁盘模式为gpt. 先用键盘选择Instal ...

  4. dump命令详解

    1.简介: dump命令用于备份文件系统. dump为备份工具程序,可将目录或整个文件系统备份至指定的设备,或备份成一个大文件. 2.语法: dump [-cnu][-0123456789][-b & ...

  5. MySql数据库执行insert时候报错:Column count doesn't match value count at row 1

    遇到这个问题之后,第一反应就是前后列数不等造成的,但是我检查SQL之后,发现列数是相同得,但是插入还是有问题,然后又写了简单得SQL只插入不为空得字段,执行还是报这个错,最后请教了高人,指点之后,大概 ...

  6. Ganglia监控扩展实现机制

    Ganglia监控扩展实现机制 默认安装完成的Ganglia仅向我们提供基础的系统监控信息,通过Ganglia插件可以实现两种扩展Ganglia监控功能的方法.1.添加带内(in-band)插件,主要 ...

  7. innodb_flush_log_at_trx_commit与sync_binlog理解

    innodb_flush_log_at_trx_commit该参数控制重做日志写入磁盘的过程.我们知道 InnoDB 使用“Write Ahead Log”策略来避免数据丢失问题,即依靠重做日志来保证 ...

  8. 4-21 嵌套选择器 、块级元素和内联元素、光标、布局-overflow

    1.嵌套选择器 p{ }: 为所有 p 元素指定一个样式.(默认,,也就是说可以被改变样式) .marked{ }: 为所有 class="marked" 的元素指定一个样式. . ...

  9. JavaSE基础知识(5)—面向对象(5.6 static关键字)

    一.说明 static属于一种修饰符,可以用于修饰 属性.方法.初始化块.内部类用static修饰的成员,称为静态成员不用static修饰的成员,称为普通成员 二.静态属性的特点 1.生命周期 静态属 ...

  10. Requset模块

    Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库 各种请求方式: #!/urs/bin/evn python # -*- cod ...