迟到的补题。。。。

题意:
你可以用花费 a a a元,使得 x x x或者 y y y不同时加 1 1 1或者减 1 1 1,你也可以花费 b b b元使得 x , y x,y x,y同时加 1 1 1或者减 1 1 1,问你最少花费多少钱使得 x = y = 0 x=y=0 x=y=0
思路:
无论你是同时还是单一操作,你都要先使得 x = y x=y x=y,然后再考虑使用同时加减还是单一加减更优。
代码:

#include<bits/stdc++.h>
using namespace std;
 
const int maxn = 2e5 + 10;
typedef long long int ll;
void solved(){
	int t;cin>>t;
	while(t--){
		ll x,y,a,b;cin>>x>>y>>a>>b;
		cout<<(max(x,y)-min(x,y)) * a + min(min(x,y) * b,min(x,y) * 2 * a)<<endl;
	}	
}
int main(){
	solved();
	return 0;
} 



题目大意:
给你一个 01 01 01字符串 t t t,要你生产一个字符串 s s s,使得 t t t s s s的子串,并且 s s s的循环周期最短并且 s s s的长度 < = 2 t <=2t <=2t
思路:
容易发现如果 t t t本身只包含 0 1 0或者1 01字符串的时候,循环周期为 1 1 1且最短,这个时候直接输出即可。当 t t t包含 01 01 01字符串的时候我们不可能生产出比周期 1 1 1更短的字符串,但是周期 2 2 2确实可以生产的,只需要保证 s s s的长度是 t t t的两倍,那么 t t t一定是 s s s的字串,并且把 s s s生成 01010101...01 01010101...01 01010101...01这样的字符串即可,因为周期为 2 2 2最短。
代码:

#include<bits/stdc++.h>
using namespace std;
 
const int maxn = 2e5 + 10;
typedef long long int ll;
void solved(){
	int t;cin>>t;
	while(t--){
		string s;cin>>s;
		int f1 = 0,f0 = 0;
		for(int i = 0; i < s.size(); i++){
			if(s[i] == '1')f1 = 1;
			if(s[i] == '0')f0 = 1;
		}
		if(f1 && f0){
			for(int i = 0; i < s.size(); i++){
				cout<<"01";
			}
			cout<<endl;
		}else{
			cout<<s<<endl;
		}
	}
}
int main(){
	solved();
	return 0;
} 


题目大意:
给你两个十进制数字 a , b a,b a,b,和 q q q个询问,每个询问包含一个区间 L , R L,R L,R,问你这个区间满足 x x x% a a a%b ! = != != x x x% b b b% a a a的数有多少个。
思路:
x < m a x ( a , b ) x<max(a,b) x<max(a,b)的时候一定不满足。
我们可以发现当 x = l c m ( a , b ) x=lcm(a,b) x=lcm(a,b)的时候 x x x% a a a%b = = = x x x% b b b% a a a,并且 l c m + m a x ( a , b ) lcm+max(a,b) lcm+max(a,b)这一段都不满足,进而可以推广 k l c m + m a x ( a , b ) klcm+max(a,b) klcm+max(a,b)这些段不满足,换言之, l c m m a x ( a , b ) lcm - max(a,b) lcmmax(a,b)是满足条件的。所以我们需要在 L , R L,R L,R找有多少个 l c m lcm lcm,可以 R / l c m L / l c m R/lcm - L /lcm R/lcmL/lcm找出 l c m lcm lcm个数,当然还要考虑边界情况,把R可以少加的 R m a x ( a , b ) + 1 R- max(a,b) + 1 Rmax(a,b)+1加上,把L可能少减的 L m a x ( a , b ) L - max(a,b) Lmax(a,b)减掉就行了。
代码:

#include<bits/stdc++.h>
using namespace std;
 
typedef long long int ll;
void solved(){
	int t;cin>>t;
	while(t--){
		ll a,b,q;cin>>a>>b>>q;
		ll lcm = a / __gcd(a,b) * b;
		while(q--){
			ll l,r;cin>>l>>r;
			if(r < max(a,b)){
				cout<<"0"<<endl;
			}else{
				ll n = r / lcm - l / lcm;
				ll ans = n * (lcm - max(a,b));
				r %= lcm;
				if(r >= max(a,b))ans += r - max(a,b) + 1;
				l %= lcm;	
				if(l > max(a,b))ans -= l - max(a,b);
				cout<<ans<<" ";
			}
		}
		cout<<endl;
	}
}
int main(){
	solved();
	return 0;
} 




题目大意:
给你 n n n个数,要你分组,每组需要满足 > = 1 >=1 >=1的个数不超过 C i Ci Ci,。。。 > = k >=k >=k的个数不超过 C k Ck Ck。要你使得分组数最少,并且输出分组方案。
思路:
为了方便处理先把所有数升序,然后找满足大于等于 a i ai ai的数有多少个 / / / c i ci ci,向上取整然后去最大值,就是最小方案数了。你可以这样理解,最大值并且大于其他所有数,其他所有分组数都满足了,这个时候只需要满足最大的这个数了,就会满足所有情况。然后把每个数依次分组填入即可(即将最大峰值缩小)。
核心: m a x ( s i / c i ) max(si/ci) max(si/ci)向上取整
代码:

#include<bits/stdc++.h>
using namespace std;
 
typedef long long int ll;
const int maxn = 2e5 + 10;
int m[maxn],c[maxn];
vector<int>ve[maxn];
void solved(){
	int n,k;cin>>n>>k;
	for(int i = 1; i <= n; i++)cin>>m[i];
	for(int i = 1; i <= k; i++)cin>>c[i];
	sort(m + 1, m + 1 + n);
	int ans = 0;
	for(int i = 1; i <= n; i++){
		ans = max(ans,((n - i + 1) - 1) / c[m[i]] + 1);
	}
	for(int i = 1; i <= n; i++){
		ve[(i - 1) % ans].push_back(m[i]);
	}
	cout<<ans<<endl;
	for(int i = 0; i < ans; i++){
		cout<<ve[i].size()<<" ";
		for(int j = 0; j < ve[i].size(); j++){
			cout<<ve[i][j]<<" ";
		}
		cout<<endl;
	}
}
int main(){
	solved();
	return 0;
}