首页 > 其他分享 >Codeforces Round 924 (Div. 2)

Codeforces Round 924 (Div. 2)

时间:2024-02-11 20:33:34浏览次数:25  
标签:int ll Codeforces long solve using Div 924 dp

不会 F 的场。

A

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t;
	cin>>t;
	while (t--){
		int a,b;
		cin>>a>>b;
		int f=0;
		if (a%2==0 && a/2!=b){
			f=1;
		}
		if (b%2==0 && b/2!=a){
			f=1;
		}
		if (f){
			cout<<"Yes\n";
		}
		else{
			cout<<"No\n";
		}
	}
	return 0;
}

B

去重二分。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 2e5+5;

int n;

void solve(){
	cin>>n;
	vector<int> v;
	for (int i=0; i<n; i++){
		int x;
		cin>>x;
		v.push_back(x);
	}
	sort(v.begin(),v.end());
	v.erase(unique(v.begin(),v.end()),v.end());
	int ans=0;
	for (int i=0; i<v.size(); i++){
		int mx=v[i]+n-1;
		int l=i,r=v.size();
		while (l+1<r){
			int mid=l+r>>1;
			if (v[mid]>mx){
				r=mid;
			}
			else{
				l=mid;
			}
		}
		ans=max(ans,l-i+1);
	}
	cout<<ans<<"\n";
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t;
	cin>>t;
	while (t--){
		solve();
	}
	return 0;
}

其实可以双指针的。

C

分别考虑是前一半还是后一半。发现 \(2k-2\mid n-x\) 或 \(2k-2 \mid n+x-2\) 才可以。同时 \(k\ge x\)。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

void solve(){
	ll n,x;
	cin>>n>>x;
	set<ll> st;
	ll y=n-x;
	for (ll i=1; i*i<=y; i++){
		if (y%i==0){
			if (i%2==0) st.insert(i);
			if ((y/i)%2==0) st.insert(y/i);
		}
	}
	y=n+x-2;
	for (ll i=1; i*i<=y; i++){
		if (y%i==0){
			if (i%2==0) st.insert(i);
			if ((y/i)%2==0) st.insert(y/i);
		}
	}
	int cnt=0;
	for (auto u : st){
		if ((u+2)/2>=x){
			cnt++;
		}
	}
	cout<<cnt<<"\n";
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t;
	cin>>t;
	while (t--){
		solve();
	}
	return 0;
}

D

\(\mathcal{O}(N+\sum c)\) 做法。记录少了一个组会少掉多少战斗值。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 2e5+5;

ll n,b,X,c[N],mn[N];

void solve(){
	cin>>n>>b>>X;
	ll tot=0;
	for (int i=1; i<=n; i++){
		cin>>c[i];
		tot+=c[i];
	}
	for (int i=1; i<=tot; i++){
		mn[i]=0;
	}
	ll sum=0;
	for (int i=1; i<=n; i++){
		ll qs=c[i]*(c[i]-1)/2;
		sum+=qs;
	//	cout<<c[i]<<"::"<<qs<<"\n"; 
		for (ll j=c[i]-1; j>=1; j--){
			ll _x=c[i]/j;
			ll y=c[i]%j;
			ll x=j-y;
	//		assert(x+y==j);
			ll it=x*_x*(c[i]-_x)+y*(_x+1)*(c[i]-_x-1);
			it/=2;
	//		cout<<_x<<","<<x<<","<<y<<","<<qs<<","<<it<<"\n";
			mn[j]+=qs-it;
			qs=it;
		}
	//	cout<<",,,"<<"\n";
	}
	//cout<<sum<<"!\n";
	ll ans=0;
	for (ll i=tot; i>=1; i--){
		ans=max(ans,sum*b-(i-1)*X);
		sum-=mn[i-1];
	}
	cout<<ans<<"\n";
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t;
	cin>>t;
	while (t--){
		solve();
	}
	return 0;
}

E

你考虑最少 \(sum\) 也得有 \((x\%y)\times n\),\(y\mid sum-(x\%y)\times n\)。

你考虑你已经有了答案数组,然后数组每项都减去 \((x\%y)\),再除以 \(y\),这个数列一定是 (从 \(x\) 开始的若干项)+(一堆 \(12345\cdots\)组成的,中间以 \(0\) 间隔)。答案不存在是 \(sum<(x\%y)*\times n\) 或 \((sum-(x\%y)\times n)\%y\neq 0\) 或后面放不下了。

可以 \(dp_i\) 设为至少有做少个位置,才可以放得下 \(i\) 个 \(y\)。然后 \(dp_i\) 可以转移:\(dp_i=min\{dp_{i-a_j}+j+1\}\),\(a_j\) 是第 \(j\) 个三角形数。然后就 \(\mathcal{O}(N\sqrt{N})\) 预处理完。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 2e5+5;

int a[500];
int dp[N],ans[N],pth[N];

void init(){
	a[1]=1;
	int tot;
	for (tot=2; a[tot-1]<N; tot++){
		a[tot]=a[tot-1]+tot;
	}
	tot--;
	memset(dp,0x3f,sizeof dp);
	dp[0]=0;
	for (int i=1; i<N; i++){
		for (int j=1; j<=tot && a[j]<=i; j++){
			if (dp[i]>dp[i-a[j]]+j+1){
				dp[i]=dp[i-a[j]]+j+1;
				pth[i]=j;
			}
		}
	}
}

void solve(){
	ll n,x,y,s;
	cin>>n>>x>>y>>s;
	ll md=x%y;
	ll mn=md*n;
	if (s<mn){
		cout<<"NO\n";
		return;
	}
	if ((s-mn)%y!=0){
		cout<<"NO\n";
		return;
	}
	ll nd=(s-mn)/y;
	for (ll i=0; i<=n; i++){
		if (i==0 && x!=md){
			continue;
		}
		// 1~i: from 1
		ll sum=(x+x+(i-1)*y)*i/2;
		sum=(sum-i*md)/y;
		if (i==0){
			sum=0;
		}
		if (sum>nd){
			break;
		}
		ll rm=nd-sum;
		if (dp[rm]>(n-i)){
			continue;
		}
		// rm is good
		ans[1]=x;
		for (int j=2; j<=i; j++){
			ans[j]=ans[j-1]+y;
		}
		int tot=i;
		int cur=rm;
		while (cur){
			int p=pth[cur];
			ans[++tot]=md;
			for (ll j=1; j<=p; j++){
				ans[++tot]=j*y+md;
			}
			cur=cur-a[p];
		}
		while (tot<n){
			ans[++tot]=md;
		}
		cout<<"YES\n";
		for (int i=1; i<=n; i++){
			cout<<ans[i]<<" ";
		}
		cout<<"\n";
		//
		return;
	}
	cout<<"NO\n";
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	init();
	int t;
	cin>>t;
	while (t--){
		solve();
	}
	return 0;
}

标签:int,ll,Codeforces,long,solve,using,Div,924,dp
From: https://www.cnblogs.com/SFlyer/p/18013514

相关文章

  • Codeforces Round 924 (Div. 2)
    CodeforcesRound924(Div.2)A-RectangleCutting解题思路:初始矩形长宽为\((a,b)\),如果我们切\(a\),那么一定不能再拼接\(a\),否则一定一样。所以我们拼接\(b\),即将\(a\)对半分开得到两个\((\frac{a}{2},b)\)矩形拼接。此时,如果\(\frac{a}{2}=b\)那么拼接出来的矩形和初......
  • Codeforces Round 905 (Div. 3)
    题目链接A.先算距离,特判0的位置,最后加4#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;#defineinf0x3f3f3f3fvoidsolve(){strings;cin>>s;s=""+s;intlast=1,now,ans=0;for(inti=1;i<s.si......
  • Educational Codeforces Round 135 (Rated for Div. 2)C. Digital Logarithm(思维)
    目录题目链接题意题解代码题目链接C.DigitalLogarithm题意给两个长度位\(n\)的数组\(a\)、\(b\),一个操作\(f\)定义操作\(f\)为,\(a[i]=f(a[i])=a[i]\)的位数求最少多少次操作可以使\(a、b\)两个数组变得完全相同题解性质:对于任何数,经过两次操作我们一定可以让其变为\(......
  • CodeForces 1286C2 Madhouse (Hard version)
    洛谷传送门CF传送门可以把限制看成\(0.75n^2\)。发现\(0.75n^2=0.5n^2+2\times0.5(\frac{n}{2})^2\)。这启发我们询问一次\([1,n]\)和两次长度为\(\frac{n}{2}\)的区间。不妨问\([1,n],[1,\frac{n}{2}],[1,\frac{n}{2}+1]\)试试。注意到把\([1,\frac......
  • Educational Codeforces Round 145 (Rated for Div. 2)C. Sum on Subarrays(构造)
    很意思的一道构造题题意:给一个\(n、k\),让构造长度为n的数组满足,子数组为整数的个数为k个,负数的为\(k-(n+1)*n/2\),每个数的范围为\([-1000,1000]\)这种构造题可以考虑就是前一段可以一直用一样的、最小的。我们观察可以发现\(k+k-(n+1)*n/2=(n+1)*n/2\)也就是所有子数组......
  • CodeForces 1927G Paint Charges
    洛谷传送门CF传送门看到\(n\le100\)考虑\(O(\text{poly}(n))\)dp。发现从左向右决策,因为一个点可以向左或向右覆盖,所以需要记最靠左的未覆盖的位置\(j\)和最靠右的已覆盖位置\(k\),状态就是\(f_{i,j,k}\),dp最小的覆盖次数。转移的讨论很简单。考虑不覆盖还是向左......
  • Codeforces Round 919 (Div. 2)
    https://codeforces.com/contest/1920B还行,C、Egood(E据说是很典的dp但我是dp苦手),D、F1无聊,F2不会A.SatisfyingConstraints*800有\(n\)个条件,每个条件形如\(x\gek,x\lek\)或\(x\neqk\),\(k\)为整数。问满足条件的整数\(x\)的个数。先处理\(\ge,\le\),得到限制......
  • CF1863F Divide, XOR, and Conquer 题解
    简要题意你有两个指针\(l,r\)初始时\(l=1,r=n\)。你可以操作若干次知道\(l=r\)。每次操作你可以选择一个整数\(k\in[l,r)\),记\(x=\bigoplus_{i=l}^ka_i,y=\bigoplus_{i=k+1}^ra_i\)。如果\(x\leqy\),你可以令\(l=k+1\)。如果\(x\geqy\),你可以令\(r=k\)。......
  • Codeforces Round 923 (Div. 3)赛后总结
    CodeforcesRound923(Div.3)A没什么好说的,纯秒。B一开始不知道怎么做,后面用了一个比较麻烦复杂的思路,可以做,但是开数时漏了数组0下标,导致样例一部分一直是空的。C非常简单的一道题,判断条件也比较好找,但是再提醒一遍自己,数组开大点,应该数组开小了,导致样例8没过真的气,最后......
  • Codeforces Round 260 (Div. 1)A. Boredom(dp)
    最开始写了一发贪心wa了,然后这种选和不选的组合优化问题,一般是考虑动态规划\(dp[i][0]:\)表示第i个数不选的最大值\(dp[i][1]:\)表示第i个数选的最大值考虑转移:\(dp[i][0]=max(dp[i-1][1],dp[i-1][0])\)\(dp[i][1]=dp[i-1][1]+a[i]*i\)需要将每一个数用一个桶统计次数因......