首页 > 其他分享 >AtCoder Regular Contest 067

AtCoder Regular Contest 067

时间:2025-01-12 20:11:10浏览次数:1  
标签:AtCoder 067 ... int max mid long Regular arc067

\(AT\_arc067\_a\)
https://www.luogu.com.cn/problem/AT_arc067_a
题解:筛出\(1\sim n\)中质数,计算每个质数出现次数,再累乘即可。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=1010,P=1e9+7;

int n;
int buc[N];
int prime[N],cnt;
bool st[N];

void sieve(int n){
	for(int i=2; i<=n; i++){
		if(!st[i]) prime[++cnt]=i;
		for(int j=1; j<=cnt&&prime[j]<=n/i; j++){
			st[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}

int main(){
	sieve(N-1);
	cin >> n;
	for(int i=1; i<=cnt; i++)
		for(int j=prime[i]; j<=n; j*=prime[i]) buc[i]+=n/j;
	int ans=1;
	for(int i=1; i<=cnt; i++) ans=(LL)ans*(buc[i]+1)%P;
	cout << ans << endl;
	return 0;
}

\(AT\_arc067\_b\)
https://www.luogu.com.cn/problem/AT_arc067_b
题解:由于所有城市都需要到达,所以可看成每条边都必须走,将每条边的两种走法取最小,并累加即可。

#include <bits/stdc++.h>
#define int long long

using namespace std;

signed main(){
	int n,a,b;
	cin >> n >> a >> b;
	int last;
	cin >> last;
	int ans=0;
	for(int i=2; i<=n; i++){
		int x;
		cin >> x;
		ans+=min(b,(x-last)*a);
		last=x;
	}
	cout << ans << endl;
	return 0;
}

\(AT\_arc067\_c\)
https://www.luogu.com.cn/problem/AT_arc067_c
题解:考虑\(dp\),令\(f(i,j)\)为考虑人数为\(a\sim i\)的组,共选了\(j\)个人的方案数目。
有转移\(f(i,j)=f(i-1,j)+\sum[c(n-(j-k),k)*g(k,\frac{k}{i})*f(i-1,j-k)],i|k,i*c\leq k\leq i*d,k\leq j\)。
其中\(c(i,j)\)代表从\(i\)个人中选\(j\)个人的方案数,\(g(i,j)\)为将\(i\)个人等分为\(j\)组的方案数。
其中\(c(i,j)=c(i-1,j)+c(i-1,j-1),g(i,j)=\frac{1}{j!}\prod c(i-k*\frac{i}{j},\frac{i}{j}),\frac{i}{j}|k,0\leq k\leq j-1\)。
\(c\)递推复杂度为\(O(n^2)\),\(f,g\)递推复杂度均为\(O(n^2logn)\)。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=1010,P=1e9+7;

int n,a,b,c,d;
int fac[N],inv[N];
int C[N][N],g[N][N],f[N][N];

int qpow(int a,int b){
	int res=1;
	while(b){
		if(b&1) res=(LL)res*a%P;
		a=(LL)a*a%P;
		b>>=1;
	}
	return res;
}

int main(){
	fac[0]=1;
	for(int i=1; i<N; i++) fac[i]=(LL)fac[i-1]*i%P;
	for(int i=0; i<N; i++) inv[i]=qpow(fac[i],P-2);
	for(int i=0; i<N; i++) C[i][0]=1;
	for(int i=1; i<N; i++)
		for(int j=1; j<N; j++)
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
	for(int i=1; i<N; i++)
		for(int j=1; j<=i; j++){
			if(i%j) continue;
			g[i][j]=1;
			for(int k=0; k<=j-1; k++) 
				g[i][j]=(LL)g[i][j]*C[i-i/j*k][i/j]%P;
			g[i][j]=(LL)g[i][j]*inv[j]%P;
		}
	cin >> n >> a >> b >> c >> d;
	f[a-1][0]=1;
	for(int i=a; i<=b; i++)
		for(int j=0; j<=n; j++){
			f[i][j]=f[i-1][j];
			for(int k=i*c; k<=i*d&&k<=j; k+=i)
				f[i][j]=(f[i][j]+(LL)C[n-(j-k)][k]*g[k][k/i]%P*f[i-1][j-k])%P;
		}
	cout << f[b][n] << endl;
	return 0;
}

\(AT\_arc067\_d\)
https://www.luogu.com.cn/problem/AT_arc067_d
题解:考虑暴力枚举左右端点,计算贡献即为\(\sum_{j} \max(b_{l,j},b_{l+1,j},...,b_{r,j})\),对每个票券,预处理\(st\)表即可。
考虑优化,令\(f(i)\)为左端点为\(i\)时对应的最优右端点,发现\(f(i)\)存在单调性。
证明:假设有\(i<j\),且\(f(i)>f(j)\),对\(l=i\)来说,\(r=f(i)\)优于\(r=f(j)\),这说明\(max(f(j)+1,...,f(i))-max(i,...,f(j))>sum(f(i))-sum(f(j))\)。则当\(l=j\)时,\(max(f(j)+1,...,f(i))-max(j,...,f(j))>max(f(j)+1,...,f(i))-max(i,...,f(j))>sum(f(i))-sum(f(j))\),这同样说明\(r=f(i)\)比\(r=f(j)\)优秀,矛盾,于是\(f(i)\leq f(j)\),则\(f\)存在单调性。
考虑经典分治做法,令\(solve(l,r,L,R)\)为\(i\)在\(l\sim r\)时候,\(f(i)\)在\(L\sim R\)。直接枚举\(j\in [\max(mid,L),R]\),计算得到\(f(mid)\),递归处理\(solve(l,mid-1,L,f(mid)),solve(mid+1,r,f(mid),R)\)即可。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=210,M=5010;

int n,m,lg;
int a[M],b[M][N],len[M];
int g[M],f[N][2*M][16];
LL s[N];

inline int query(int t,int l,int r){
	int k=len[r-l+1];
	return max(f[t][l][k],f[t][r-(1<<k)+1][k]);
}

LL calc(int x,int y){
	LL res=0;
	for(int i=1; i<=m; i++) res+=query(i,x,y);
	res-=s[y]-s[x];
	return res;
}

void solve(int l,int r,int L,int R){
	if(l>r) return;
	int mid=l+r>>1,pos=max(L,mid);
	for(int i=max(L,mid); i<=R; i++)
		if(calc(mid,i)>calc(mid,pos)) pos=i;
	g[mid]=pos;
	if(l==r) return;
	solve(l,mid-1,L,pos);
	solve(mid+1,r,pos,R);
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	lg=(int)(log(n)/log(2))+1;
	for(int i=1; i<=n; i++) len[i]=log(i)/log(2);
	for(int i=2; i<=n; i++) cin >> a[i];
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++) cin >> b[i][j];
	for(int i=1; i<=m; i++)
		for(int j=1; j<=n; j++) f[i][j][0]=b[j][i];
	for(int i=1; i<=m; i++)
		for(int k=1; k<=lg; k++)
			for(int j=1; j<=n; j++)
				f[i][j][k]=max(f[i][j][k-1],f[i][j+(1<<(k-1))][k-1]);
	for(int i=2; i<=n; i++) s[i]=s[i-1]+a[i];
	solve(1,n,1,n);
	LL ans=0;
	for(int i=1; i<=n; i++) ans=max(ans,calc(i,g[i]));
	cout << ans << endl;
	return 0;
}

标签:AtCoder,067,...,int,max,mid,long,Regular,arc067
From: https://www.cnblogs.com/lastxuans/p/18666184

相关文章

  • AtCoder Regular Contest 066(缺d)
    \(AT\_arc066\_a\)https://www.luogu.com.cn/problem/AT_arc066_a题解:长度为\(n\)的队列,其\(A\)数组固定,直接判断题目给定\(A\)数组是否符合题意即可。若符合题意,答案为\(2^{\frac{n}{2}}\),否则答案为\(0\)。#include<bits/stdc++.h>usingnamespacestd;typedeflonglon......
  • atcoder 388 b-e题
    binclude<bits/stdc++.h>usingnamespacestd;/**@brief主函数,程序入口@returnint返回值为0,表示程序正常结束*/intmain(){//输入数组长度n和天数dintn,d;cin>>n>>d;//定义一个vector,用于存储输入数据vector<pair<int,int>>a(n);//输入数组a的元......
  • Atcoder ABC388F Dangerous Sugoroku 题解 [ 蓝 ] [ 矩阵加速 ] [ 状压矩乘 ] [ 模拟
    DangerousSugoroku:赛时写了矩乘T飞了,受到sunkuangzheng大佬的启发才知道要状压矩乘。暴力矩乘思路直接像过河那样写模拟细节非常多,于是考虑像美食家一样的思路,利用矩阵分段加速。定义\(dp_i\)表示\(i\)能否到达,则有如下转移:\[dp_{i}=\bigvee_{j=i-B}^{i-A}dp_{j}\]......
  • Atcoder ABC387F Count Arrays 题解 [ 绿 ] [ 基环树 ] [ 树形 dp ] [ 前缀和优化 ]
    CountArrays:一眼秒的计数题。思路显然,把小于等于的条件化为大的向小的连单向边,每个数的入度都是\(1\),就会形成一个基环树森林。那么考虑这个环上能填什么数。因为所有数都小于等于他后面的数,所以所有数都只能相等。这就启发我们在基环树上缩点之后再进行计数。那么当缩完点......
  • AtCoder Beginner Contest 388 (abc388) 赛后复盘
    为什么不会E????A-B模拟即可。C每一个大麻薯可以和所有小于等于自己\(\frac12\)的麻薯结合,二分即可。时间复杂度\(O(n\logn)\)。点击查看代码#include<bits/stdc++.h>#definelllonglong#definei128__int128#definemem(a,b)memset((a),(b),sizeof(a))#def......
  • HHKB Programming Contest 2025(AtCoder Beginner Contest 388)
    A-?UPC题意:给你一个字符串,把他的第一个字符和"UPC"输出。输出即可。点击查看代码voidsolve(){std::strings;std::cin>>s;std::cout<<s[0]<<"UPC\n";}B-HeavySnake题意:n条蛇由厚度和长度,重量为厚度乘长度,问长度加上1~k时,最大的蛇的重量分别......
  • AtCoder Beginner Contest 387
    A-HappyNewYear2025题意给定正整数\(A,B\),求\((A+B)^2\)思路模拟代码点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>pii;constintmxn=1e6+5;voidsolve(){ inta,b; cin>>a......
  • VP UNIQUE VISION Programming Contest 2024 Christmas (AtCoder Beginner Contest 38
    A-Equally题意:给你三个数,判断能不能分成大于一组后每组和相等。只可能分成两个和一个或者三组一个的。点击查看代码voidsolve(){inta,b,c;std::cin>>a>>b>>c;if((a==b&&b==c)||(a+b==c)||(b+c)==a||(a+c)==b){ s......
  • Atcoder ABC329E Stamp 题解 [ 绿 ] [ 线性 dp ]
    Stamp:难点主要在dp转移的细节与分讨上,但通过改变状态设计可以大大简化分讨细节的题。观察首先要有一个观察:只要某一个前缀能被覆盖出来,那么无论它后面多出来多少,后面的字符串都可以帮他重新覆盖回去。这也就是dp为啥没有后效性的原因。除此之外,还要注意一个字符串不仅能在......
  • VP AtCoder Beginner Contest 387
    A-HappyNewYear2025按题意输出即可。点击查看代码voidsolve(){inta,b;std::cin>>a>>b;std::cout<<(a+b)*(a+b)<<"\n";}B-9x9Sum直接遍历累加满足不等于x的数即可,注意这个九九乘法表是9*9的矩阵,不是我们学的下三角。点击查看......