文章目录

传送门

GGG题略难,膜了一波zhouyuyang{\color{red} zhouyuyang}zhouyuyang巨佬的代码。

其余都挺清真的。


A题

传送门

题意:你有sss元钱,现在每颗糖ccc元,每买aaa颗会送你bbb颗,问最多买几颗糖。


思路:按照题意模拟。

代码:

#include<bits/stdc++.h>
#define ri register int
#define int long long
#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;
signed main(){
	for(ri s,a,b,c,tt=read();tt;--tt){
		s=read(),a=read(),b=read(),c=read();
		cout<<(ll)s/c/a*(a+b)+((s-s/c/a*c*a)/c)<<'\n';
	}
	return 0;
}

B题

传送门

题意:给你nnn个点mmm条边让你随意构造无向图,称度为000的点为孤立点,问孤立点数量的最小值和最大值。


思路:

要使得数量最小显然每两个点连一条边,数量最大的话显然尽量拿去建完全图,随便判一判就完了。

注意m读入可能会爆int!!!233333333333

代码:

#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++;
}
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;
}
signed main(){
	ll n=read(),m=read();
	cout<<max(0ll,n-m*2)<<' ';
	for(ll i=0;;++i){
		if(i*(i-1)/2<m)continue;
		cout<<n-i;
		break;
	}
	return 0;
}

C题

传送门

题意:给你一排积木,没个积木有高度hih_ihi​。

让你每次指定一个高度把所有高于它的部分都砍掉,每次砍的代价是砍掉的所有高度之和,问如果每次砍的代价都不能超过给定的kkk最少砍几次。


思路:考虑时间倒流,改为每次加一部分,预处理前缀和+二分求每次可以走的最上点即可。

代码:

#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++;
}
typedef long long ll;
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,k,a[N],mn=0x3f3f3f3f,mx=-0x3f3f3f3f;
ll cnt[N],det[N];
signed main(){
	n=read(),k=read();
	for(ri i=1;i<=n;++i)a[i]=read();
	sort(a+1,a+n+1);
	for(ri i=1;i<=n;++i){
		++det[a[1]],--det[a[i]+1];
	}
	mn=a[1],mx=a[n];
	for(ri i=mn;i<=mx;++i)cnt[i]=cnt[i-1]+det[i];
	for(ri i=mn+1;i<=mx;++i)cnt[i]+=cnt[i-1];
	int turn=0;
	while(mn!=mx){
		++turn;
		int l=mn+1,r=mx,res=mn+1;
		while(l<=r){
			int mid=l+r>>1;
			if(cnt[mid]-cnt[mn]<=k)l=mid+1,res=mid;
			else r=mid-1;
		}
		mn=res;
	}
	cout<<turn;
	return 0;
}

D题

传送门

题意:给你一个n∗nn*nn∗n的国际象棋,每个格子上有一个111~n2n^2n2之间的正整数,每个格子上的数互不相同。你有三个棋子象,车和马,每次可以选择切换一种棋子或者走一步,问从111所在格子走到222所在格子再走到333所在格子这样下去一直走到n2n^2n2所在格子所需的最短步数,以及在所有最短的方案中最小的换棋子的次数。


思路:直接暴力建边跑n2n^2n2次最短路即可。

注意车和象可以分别对行,列,主对角线,副对角线建虚点优化边数。

代码:

#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=15,inf=0x3f3f3f3f;
int a[15][15],h[N],l[N],x[N<<1],y[N<<1],n,val[1005],tot;
struct Node{int v,w,col;};
vector<Node>e[1005];
inline void add(int u,int v,int w,int col){e[u].push_back((Node){v,w,col});}
map<pii,bool>in;
map<pii,pii>pred;
inline void solve(){
	static int hd,tl,s,t;
	static pii q[1005],dis[1005][4];
	dis[1][1]=pii(0,0),dis[1][2]=pii(0,0),dis[1][3]=pii(0,0);
	for(ri tt=1;tt<n*n;++tt){
		s=tt,t=tt+1;
		for(ri i=1;i<=tot;++i){
			if(i==s)continue;
			for(ri j=1;j<=3;++j)dis[i][j]=pii(inf,inf);
		}
		hd=1,tl=0;
		in[q[++tl]=pii(s,1)]=1,in[q[++tl]=pii(s,2)]=1,in[q[++tl]=pii(s,3)]=1;
		pred.clear();
		while(hd<=tl){
			pii x=q[hd++];
			in[x]=0;
			for(ri i=0,v,w,col;i<e[x.fi].size();++i){
				v=e[x.fi][i].v,w=e[x.fi][i].w,col=e[x.fi][i].col;
				pii tmp=pii(dis[x.fi][x.se].fi+w+val[v]+(x.se!=col),dis[x.fi][x.se].se+(x.se!=col));
				if(tmp<dis[v][col]){
					dis[v][col]=tmp;
					pred[pii(v,col)]=x;
					if(!in[pii(v,col)])in[q[++tl]=pii(v,col)]=1;
				}
			}
		}
	}
	pii res=min(min(dis[t][1],dis[t][2]),dis[t][3]);
	cout<<res.fi<<' '<<res.se<<'\n';
}
int main(){
	n=read();
	for(ri i=1;i<=n;++i)for(ri j=1;j<=n;++j)a[i][j]=read();
	for(ri i=1;i<=n;++i)for(ri j=1;j<=n;++j){
		if(i>1&&j>2)add(a[i][j],a[i-1][j-2],1,1);
		if(i>1&&j<n-1)add(a[i][j],a[i-1][j+2],1,1);
		if(i>2&&j>1)add(a[i][j],a[i-2][j-1],1,1);
		if(i>2&&j<n)add(a[i][j],a[i-2][j+1],1,1);
		if(i<n&&j>2)add(a[i][j],a[i+1][j-2],1,1);
		if(i<n&&j<n-1)add(a[i][j],a[i+1][j+2],1,1);
		if(i<n-1&&j>1)add(a[i][j],a[i+2][j-1],1,1);
		if(i<n-1&&j<n)add(a[i][j],a[i+2][j+1],1,1);
	}
	tot=n*n;
	for(ri i=1;i<=n;++i){
		val[h[i]=++tot]=1;
		for(ri j=1;j<=n;++j)add(a[i][j],h[i],0,2),add(h[i],a[i][j],0,2);
	}
	for(ri i=1;i<=n;++i){
		val[l[i]=++tot]=1;
		for(ri j=1;j<=n;++j)add(a[j][i],l[i],0,2),add(l[i],a[j][i],0,2);
	}
	for(ri det,i=1;i<=n*2-1;++i){
		val[x[i]=++tot]=1,det=i-n;
		for(ri j=1;j<=n;++j)if(j+det>=1&&j+det<=n)
		add(a[j][j+det],x[i],0,3),add(x[i],a[j][j+det],0,3);
	}
	for(ri sum,i=1;i<=n*2-1;++i){
		val[y[i]=++tot]=1,sum=i+1;
		for(ri j=1;j<=n;++j)if(sum-j>=1&&sum-j<=n)
		add(a[j][sum-j],y[i],0,3),add(y[i],a[j][sum-j],0,3);
	}
	solve();
	return 0;
}

E题

传送门

题意:给一个长度为n,字符集为A的字符串,以及m个数字b,对于任意数字bib_ibi​足长度为bib_ibi​的前缀和后缀先反转再交换位置后形成的新串与原串视作相等,问存在多少不同串。


思路:把bbb排序,然后方案只跟起差分数列有关,显然对于两个长度都等于某一个bib_ibi​的串A,BA,BA,B如果A&lt;BA&lt;BA<B就可以产生一次贡献。

于是只用处理询问一个f(x)f(x)f(x)表示从长度为xxx的所有串中选出来两个,A&lt;BA&lt;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=2e5+5,mod=998244353,inv2=499122177;
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 int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;}
int n,m,a,b[N],ans;
inline int f(const int&x){int tmp=ksm(a,x);return mul(mul(tmp,tmp+1),inv2);}
int main(){
	n=read(),m=read(),a=read();
	for(ri i=1;i<=m;++i)b[i]=read();
	ans=mul(ksm(a,n-2*b[m]),f(b[1]));
	for(ri i=2;i<=m;++i)ans=mul(ans,f(b[i]-b[i-1]));
	cout<<ans;
	return 0;
}

F题

传送门

题意:给你一棵树。

你从根节点111出发有如下两种走法:

  1. 走到该节点子树中的某个叶子
  2. 如果你在一个叶子上,可以选择走到你的111~kkk级祖先。

问你最后能够访问到的不同叶子数的最大值。


思路:

吐槽:想长链剖分和线段树想了好久然后突然发现一道NOIP难度的树形dp

gig_igi​表示iii向子树中走且最后能回到iii的最大答案,fif_ifi​则表示iii向子树中最后不必回到iii的最大答案。

然后从儿子转移一下就完了。

代码:

#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=1e6+5;
int n,k,f[N],g[N],dep[N],mndep[N];
vector<int>e[N];
void dfs(int p){
	mndep[p]=0x3f3f3f3f;
	if(!e[p].size()){f[p]=g[p]=1,mndep[p]=dep[p];return;}
	for(ri i=0,v;i<e[p].size();++i){
		dep[v=e[p][i]]=dep[p]+1,dfs(v),mndep[p]=min(mndep[p],mndep[v]);
		if(mndep[v]-dep[p]<=k)g[p]+=g[v],f[p]+=g[v];
	}
	int sum=f[p];
	for(ri i=0,v;i<e[p].size();++i)f[p]=max(f[p],sum-(mndep[v=e[p][i]]-dep[p]<=k?g[v]:0)+f[v]);
}
int main(){
	n=read(),k=read();
	for(ri i=2;i<=n;++i)e[read()].push_back(i);
	dfs(1);
	cout<<max(f[1],g[1]);
	return 0;
}

G题

传送门

题意:给你一个字符串斐波那契数列,F0=F_0=F0​="000",F1=F_1=F1​="111",Fi=Fi−2+Fi−1F_i=F_{i-2}+F_{i-1}Fi​=Fi−2​+Fi−1​,令AFiA_{F_i}AFi​​表示这个串的所有后缀排序后的序列,问这个序列第kkk项的前mmm个字符。


思路:

我们相当于二分一样每次按位考虑走0/10/10/1就完了。

代码(照着zhouoyuyang{\color {red}zhouoyuyang}zhouoyuyang的码了一遍):

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
const int N=305;
const ll lim=1e18+1;
int n,m;
ll k;
string ans="",f[15];
inline bool pre(int pos,const string&s,int st,const ll&len){
	int id=pos<=14?pos:14-(pos&1);
	return len<=f[id].size()&&!f[id].compare(0,len,s,st,len);
}
inline bool suf(int pos,const string&s,int st,const ll&len){
	int id=min(pos,14);
	return len<=f[id].size()&&!f[id].compare(f[id].size()-len,len,s,st,len);
}
inline ll calc(const int&n,const string&s){
	static ll g[N];
	for(ri i=0;i<=n;++i){
		if(i<2){g[i]=f[i]==s;continue;}
		g[i]=g[i-1]+g[i-2];
		for(ri up=s.size(),j=1;j<up;++j)if(suf(i-2,s,0,j)&&pre(i-1,s,j,up-j))++g[i];
		g[i]=min(g[i],lim);
	}
	return g[n];
}
int main(){
	f[0]="0",f[1]="1";
	for(ri i=2;i<=14;++i)f[i]=f[i-2]+f[i-1];
	scanf("%d%lld%d",&n,&k,&m);
	ll cnt0,ext;
	for(ri i=1;i<=m;++i){
		cnt0=calc(n,ans+'0');
		ll ext=ans!=""&&suf(n,ans,0,ans.size());
		if(k<=ext)break;
		if(k<=ext+cnt0)k-=ext,ans+='0';
		else k-=ext+cnt0,ans+='1';
	}
	cout<<ans;
	return 0;
}

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

  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 888 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意简述:给一个数列,问有多少个峰值点(同时比两边都大/小的点) 思路:按照题意模拟. 代码: #include<bit ...

  9. Codeforces 884 简要题解

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

随机推荐

  1. U3D 设置帧率与垂直同步

    1,设置帧率: Application.targetFrameRate = 60: //-1为无限制 2,垂直同步 project settings -> quality,任何level的垂直同 ...

  2. fopen特殊模式r+, w+, a+辨析

    fopen模式分两大类,即 TEXT模式:r, w, a, r+, w+, a+ BIN模式:rb, wb, ab, r+b, w+b, a+b 模式 读指针初始位置 写指针初始位置 模式用途 详细说 ...

  3. could not open input file 错误

    配置laravel时遇到的小错误 ps:php -S localhost:81 -t 框架目录/public S大写 端口不要被占用

  4. Intel 82599网卡异常挂死原因

    前提背景: 生产环境上,服务器网络突然断链,ssh连接失败. 问题初步定位: 查找内核日志,得到网卡异常信息 Jan 24 11:52:43 localhost kernel: ixgbe 0000: ...

  5. Django SCRF跨站点请求伪造

    使用Django发POSTt请求的时候经常会遇到Forbidden的错误,然后直接了当的方法就是去setting里面吧csrf中间件注释掉,其实csrf是django给我们提供的防护措施. CSRF就 ...

  6. python的django基础篇

    一.Django基础 Django 是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网站! Django的特点: 强大的数据库功能:拥有强大的数据库操作接口(QueryS ...

  7. python--第十五天总结(jquery)

    空格:$('parent childchild')表示获取parent下的所有的childchild节点,所有的子孙. 大于号:$('parent > child')表示获取parent下的所有 ...

  8. linux下mycat自启动方法

    每次开机都要启动mycat,网上看了好多都是用shell脚本来实现mycat开机自启动,后来看到一种方法,直接修改系统文件来实现,已经实践过,方法有效. 1.修改脚本文件rc.local:vim /e ...

  9. 下拉js的实现

    这个JS是出自一个浴室柜网站 $(document).ready(function(){ $(".side_nav_3").hover(function() { $(this).f ...

  10. vue使用qrcode插件生成二维码

    参考:https://www.jianshu.com/p/d3883e020d99 步骤: 第一步:vue-cli下载插件 cnpm install --save qrcodejs2 第二步:组件中引 ...