文章目录

传送门

A题

传送门

题意简述:问你能不能把一个数字串切成若干块,使得切出来的kkk个数k≤2k\le2k≤2满足a1&lt;a2&lt;...&lt;aka_1&lt;a_2&lt;...&lt;a_ka1​<a2​<...<ak​


思路:模拟。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
int n;
char s[500];
int main(){
	for(ri tt=read();tt;--tt){
		n=read(),scanf("%s",s+1);
		if(n==2&&s[1]>=s[2]){puts("NO");continue;}
		puts("YES"),puts("2");
		cout<<s[1]<<' ';
		for(ri i=2;i<=n;++i)cout<<s[i];
		puts("");
	}
	return 0;
}

B题

传送门

题意简述:

问第kkk大数根为iii的数是多少0≤i≤90\le i\le90≤i≤9


思路:一个数的数根等于它mod&ThinSpace;&ThinSpace;9\mod9mod9的值。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
inline ll read(){
	ll ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=400;
int n,x;
ll k;
int main(){
	for(ri tt=read();tt;--tt){
		k=read(),x=read();
		cout<<(k-1)*9+x<<'\n';
	}
	return 0;
}

C题

传送门

题意简述:给nnn个数和一个值kkk,有一个262626个字符的键盘,每个键不能连续按超过kkk次,现在给你一个按键序列和对于每次按键可以得到的权值,问最后可以得到的总权值是多少(注意如果按了kkk个aaa后按一个bbb的话又可以再按kkk次aaa)。


思路:

我们把相同数字段全部提出来,分别求出前kkk大加起来即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=2e5+5;
int n,k,a[N];
char s[N];
priority_queue<int>q;
ll ans=0;
inline void solve(int l,int r){
	while(!q.empty())q.pop();
	for(ri i=l;i<=r;++i)q.push(a[i]);
	for(ri i=1;i<=k;++i){
		if(q.empty())break;
		ans+=q.top(),q.pop();
	}
}
int main(){
	n=read(),k=read();
	for(ri i=1;i<=n;++i)a[i]=read();
	scanf("%s",s+1);
	ans=0;
	for(ri l=1,r=1;l<=n;l=r+1,r=l){
		while(r<=n&&s[r]==s[r+1])++r;
		solve(l,r);
	}
	cout<<ans;
	return 0;
}

D题

传送门

题意简述:有一个n∗nn*nn∗n的010101矩阵aaa,问你能不能构造出一个k∗k,满足k∣nk*k,满足k|nk∗k,满足k∣n的矩阵bbb使得ai,j=b⌊ik⌋,⌊jk⌋a_{i,j}=b_{\lfloor{\frac ik}\rfloor,\lfloor{\frac jk}\rfloor}ai,j​=b⌊ki​⌋,⌊kj​⌋​


思路:暴力枚举iii,利用前缀和优化checkcheckcheck即可

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=5205;
int n,sum[N][N];
char s[N];
int main(){
	n=read();
	for(ri i=1;i<=n;++i){
		scanf("%s",s+1);
		for(ri j=1,v;j<=n;j+=4){
			if(s[(j+3)/4]>='A'&&s[(j+3)/4]<='Z')v=s[(j+3)/4]-'A'+10;
			else v=s[(j+3)/4]-'0';
			sum[i][j]=(v>>3)&1;
			sum[i][j+1]=(v>>2)&1;
			sum[i][j+2]=(v>>1)&1;
			sum[i][j+3]=v&1;
		}
	}
	for(ri i=1;i<=n;++i)for(ri j=1;j<=n;++j)sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+sum[i][j];
	for(ri i=n;i;--i){
		if(n!=n/i*i)continue;
		bool f=1;
		for(ri x=1;x*i<=n;++x){
			for(ri y=1,v;y*i<=n;++y){
				v=sum[i*x][i*y]-sum[i*x][i*(y-1)]-sum[i*(x-1)][i*y]+sum[i*(x-1)][i*(y-1)];
				f&=v==0||v==i*i;
			}
		}
		if(f)return cout<<i,0;
	}
	return 0;
}

E题

传送门

题意简述:

给出一个010101串,每次可以选择消去连续的一段,贡献是alen,lena_{len},lenalen​,len表示消去长度,aia_iai​会给出,问消去整个串的最大贡献。


思路:

先dpdpdp出真·aia_iai​(既考虑aia_iai​和aj+ai−ja_j+a_{i-j}aj​+ai−j​哪个大,如果后者大就更新前者)。

然后可以区间dpdpdp,fl,rf_{l,r}fl,r​表示区间[l,r][l,r][l,r]的贡献,gl,r,k,0/1g_{l,r,k,0/1}gl,r,k,0/1​表示区间[l,r][l,r][l,r]消得只剩下kkk个连续的0/10/10/1的最大贡献,枚举转移即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
typedef long long ll;
const int N=105;
int n,a[N],sum[N][N];
ll f[N],g[N][N][2];
char s[N];
inline void update(ll&a,ll b){a=b>a?b:a;}
int main(){
	memset(g,-0x3f,sizeof(g));
	n=read(),scanf("%s",s+1);
	for(ri i=1;i<=n;++i){
		a[i]=f[i]=read();
		for(ri j=1;j<i;++j)f[i]=max(f[i],f[j]+f[i-j]);
	}
	int cnt0=0,cnt1=0;
	for(ri i=1;i<=n;++i)sum[1][i]=sum[1][i-1]+(s[i]=='1'),g[i][i][s[i]-'0']=f[1];
	for(ri l=1;l<=n;++l)for(ri r=l;r<=n;++r)sum[l][r]=sum[1][r]-sum[1][l-1];
	for(ri len=2;len<=n;++len){
		for(ri l=1,r=l+len-1;r<=n;++l,++r){
			if(s[l+1]=='0')update(g[l][r][0],g[l+1][r][0]+f[r-l+1-sum[l][r]]-f[r-l-sum[l][r]]);
			if(s[r-1]=='0')update(g[l][r][0],g[l][r-1][0]+f[r-l+1-sum[l][r]]-f[r-l-sum[l][r]]);
			if(s[l+1]=='1')update(g[l][r][1],g[l+1][r][1]+f[sum[l][r]]-f[sum[l][r]-1]);
			if(s[r-1]=='1')update(g[l][r][1],g[l][r-1][1]+f[sum[l][r]]-f[sum[l][r]-1]);
			for(ri k=l;k<r;++k){
				update(g[l][r][0],g[l][k][0]+g[k+1][r][0]);
				update(g[l][r][0],g[l][k][0]+g[k+1][r][1]);
				update(g[l][r][0],g[l][k][1]+g[k+1][r][0]);
				update(g[l][r][1],g[l][k][0]+g[k+1][r][1]);
				update(g[l][r][1],g[l][k][1]+g[k+1][r][0]);
				update(g[l][r][1],g[l][k][1]+g[k+1][r][1]);
			}
		}
	}
	cout<<max(g[1][n][0],g[1][n][1]);
	return 0;
}

F题

传送门

题意简述:

有nnn家银行,你每月初可以选择从其中一家贷款aia_iai​,然后接下来kik_iki​个月(包括这个月)每月底还bib_ibi​元,问所有贷款方案中在任意一个月中总现额的最大值。


思路:

显然有费用流做法,利用费用提前计算思想即可。

然而也可以贪心的按照bib_ibi​从大到小排序,然后fif_ifi​表示总共贷款iii个月的最大值跑一个O(n2)O(n^2)O(n2)的dpdpdp。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
typedef long long ll;
const int N=1005,M=250005;
int n;
struct Node{int a,b,c;}a[N];
ll ans=0,f[N];
inline void update(ll&a,const ll&b){a=b>a?b:a;}
inline bool cmp(const Node&a,const Node&b){return a.b>b.b;}
int main(){
	n=read();
	for(ri i=1;i<=n;++i)a[i].a=read(),a[i].b=read(),a[i].c=read();
	sort(a+1,a+n+1,cmp);
	for(ri i=1;i<=n;++i){
		for(ri j=n-1;~j;--j){
			update(f[j+1],f[j]+a[i].a-(ll)j*a[i].b);
			update(f[j],f[j]+a[i].a-(ll)a[i].c*a[i].b);
		}
	}
	for(ri i=0;i<=n;++i)update(ans,f[i]);
	cout<<ans;
	return 0;

G题

传送门

题意简述:

给出n,a,ci,din,a,c_i,d_in,a,ci​,di​,你要从中选出一段[l,r][l,r][l,r]来,贡献是a∗(r−l+1)−∑i=lrci−maxi=lr−1(di+1−di)2a*(r-l+1)-\sum_{i=l}^rc_i-max_{i=l}^{r-1}(d_{i+1}-d_i)^2a∗(r−l+1)−∑i=lr​ci​−maxi=lr−1​(di+1​−di​)2,保证ddd单增。


思路:

考虑dpdpdp,fif_ifi​表示以iii结尾序列长度至少为222的答案。

那么显然可以从iii开始往前找到一个第一个jjj使得di−di−1≤dj−dj−1d_i-d{i-1}\le d_j-d_{j-1}di​−di−1≤dj​−dj−1​

这样fif_ifi​可以由fjf_jfj​和[j,i][j,i][j,i]之间的最大后缀和转移过来,因此我们二分或者线段树求出jjj,然后更新fif_ifi​即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
typedef long long ll;
const int N=3e5+5;
int n;
ll ans=0,f[N],sum[N],a,c[N],d[N];
inline void update(ll&a,const ll&b){a=b>a?b:a;}
namespace SGT{
	#define lc (p<<1)
	#define rc (p<<1|1)
	#define mid (l+r>>1)
	ll mx[N<<2];
	inline void pushup(int p){mx[p]=max(mx[lc],mx[rc]);}
	inline void build(int p,int l,int r){
		mx[p]=-1;
		if(l==r)return;
		build(lc,l,mid),build(rc,mid+1,r),pushup(p);
	}
	inline int query(int p,int l,int r,ll v){
		if(mx[p]<v)return -1;
		if(l==r)return l;
		return mx[rc]>=v?query(rc,mid+1,r,v):query(lc,l,mid,v);
	}
	inline void update(int p,int l,int r,int k,ll v){
		if(l==r){mx[p]=v;return;}
		k<=mid?update(lc,l,mid,k,v):update(rc,mid+1,r,k,v);
		pushup(p);
	}
	#undef mid
	#undef lc
	#undef rc
}
namespace sgt{
	#define lc (p<<1)
	#define rc (p<<1|1)
	#define mid (T[p].l+T[p].r>>1)
	struct Node{int l,r;ll rs,sum;}T[N<<2];
	inline Node operator+(const Node&a,const Node&b){return (Node){a.l,b.r,max(b.rs,b.sum+a.rs),a.sum+b.sum};}
	inline void build(int p,int l,int r){
		T[p].l=l,T[p].r=r;
		if(l==r){T[p].rs=T[p].sum=a-c[l];return;}
		build(lc,l,mid),build(rc,mid+1,r),T[p]=T[lc]+T[rc];
	}
	inline Node query(int p,int ql,int qr){
		if(ql<=T[p].l&&T[p].r<=qr)return T[p];
		if(qr<=mid)return query(lc,ql,qr);
		if(ql>mid)return query(rc,ql,qr);
		return query(lc,ql,mid)+query(rc,mid+1,qr);
	}
	#undef mid
	#undef lc
	#undef rc
}
inline ll solve(int l,int r){return sgt::query(1,l,r-1).rs+a-c[r]-(d[r]-d[r-1])*(d[r]-d[r-1]);}
int main(){
	n=read(),a=read(),SGT::build(1,1,n);
	for(ri i=1;i<=n;++i)d[i]=read(),c[i]=read(),update(ans,a-c[i]),sum[i]=sum[i-1]+a-c[i];
	sgt::build(1,1,n);
	for(ri i=1;i<=n;++i){
		f[i]=-1e18;
		if(i==1)continue;
		int pos=SGT::query(1,1,n,d[i]-d[i-1]);
		if(pos==-1)pos=1;
		f[i]=max(solve(pos,i),f[pos]+sum[i]-sum[pos]);
		update(ans,f[i]),SGT::update(1,1,n,i,d[i]-d[i-1]);
	}
	cout<<ans;
	return 0;
}

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

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

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

随机推荐

  1. js改变表单的内容样式

    一.改变单个样式    var obj = document.getElementById("id");   obj.style.cssText = " display: ...

  2. PTA 7-7 六度空间(广搜)

    “六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论.这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够 ...

  3. stark组件之pop操作【模仿Django的admin】

    一.先看下什么django的admin的pop到底是个什么东西 其实就是这么一个东西, a.在添加页面,在一对多和多对多的项后加了一个+号 b.点击这个加号,会弹出对应的添加 页面,在新的添加 c.添 ...

  4. iOS 打包方式

    https://www.cnblogs.com/wengzilin/p/4601684.html

  5. day 24 socket 黏包

    socket 套接字的使用: tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端 server 端 import socket sk = socket.socket() # 实例化一个 ...

  6. 43-将javaweb项目部署到Linux服务器

    这是第二次弄了,感觉由于上次积累了点资源,这次要少走很多弯路了,再次记录下来吧. 第一次的记录:将本地的javaweb项目部署到Linux服务器的一般操作 1. 在Linux上建立数据库,我是将本地的 ...

  7. VS新建API控制器时提示“运行所选代码生成器时出错”

    使用Nuget安装microsoft.entityframeworkcore.tools这个包就行了,安装时注意版本. 根据下图提示应该是新建控制器时用到了这个包,所以安装一下就好了.之前遇到过一次, ...

  8. Linux安装命令出现如下错误:cannot find a valid baseurl for repo :base/7x86_64

    今天刚回到家,在我的虚拟机上有安装了一个Linux系统,安装好之后,想要安装如下命令,yum install wget,yum install gcc,yum install vim,发现一个也没有安 ...

  9. js sort

    排序算法 比较的过程必须通过函数抽象出来.通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法就不用关 ...

  10. MVC中利用knockout.js实现动态uniqueId

    题目比较拗口,但是这篇文章确实直说这一点. knockout.js是一个JS库,它的官网是http://knockoutjs.com/ 这篇文章的重点是knockout在工作的一个功能中的应用.最终效 ...