Educational Codeforces Round 85(Div。2)题解(ABCDE)

コンテストリンク:https : //codeforces.com/contest/1334

A.レベル統計

2つのプロパティを把握します。1つはゲームの数と通関手続きの数が単調であること、もう1つは隣接するゲームの数の変化が通関手続きの数の対応する変化以上であることです。

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll;
#define int ll
int T,n;
signed main(){
	cin>>T;
	while(T--){
		cin>>n;
		bool f=1;
		int a=-1,b=-1;
		while(n--){
			int aa,bb; cin>>aa>>bb;
			if(aa<a || bb<b)f=false;
			if(aa-a<bb-b)f=false;
			a=aa,b=bb;
		}
		cout<<(f?"YES":"NO")<<endl;
	}
	return 0;
}

B.中産階級

フォーチュン液化委員会、霧)

資産を逆の順序で並べ替えると、上位kの個人資産の資産はkとともに単調に増加しないため、最大のkを一度に見つけることができます。

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll;
#define int ll
int T,n,x;
int a[N],s,ans;
signed main(){
	cin>>T;
	while(T--){
		cin>>n>>x;
		repeat(i,1,n+1){
			cin>>a[i];
		}
		sort(a+1,a+1+n,greater<int>());
		s=ans=0;
		repeat(i,1,n+1){
			s+=a[i];
			if(s*1.0/i>=x)ans=i;
		}
		cout<<ans<<endl;
	}
	return 0;
}

C.モンスターの輪

最初に、すべてのモンスターの体力を前のモンスターの爆発ダメージに減らします(それよりも小さい場合は、ドロップする必要はありません)。次に、もう一度、i番目のモンスターを殺すために必要な追加のダメージを確認します(1つのモンスターを殺せる限り)すべてのモンスターをシリアルキルする)、最小のものを取る

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=300010; typedef long long ll; const ll INF=~0ull>>2;
#define int ll
int T,n,x;
int a[N],b[N];
signed main(){
	cin>>T;
	while(T--){
		cin>>n;
		int cost=0;
		repeat(i,0,n){
			cin>>a[i]>>b[i];
		}
		rotate(b,b+n-1,b+n); //rotate使得怪i收到的爆炸伤害是b[i]
		repeat(i,0,n){
			if(a[i]>b[i])cost+=a[i]-b[i];
		}
		int ans=INF*2;
		repeat(i,0,n){
			int now=0;
			if(a[i]>b[i])now+=-(a[i]-b[i]);
			now+=a[i];
			ans=min(ans,now);
		}
		cout<<cost+ans<<endl;
	}
	return 0;
}

D.最小オイラーサイクル

\(n = 5 \)の描くと、オイラーシーケンスは次のようになります。

\ [[1,2,1,3,1,4,1,5] + [2,3,2,4,2,5] + [3,4,3,5] + [4,5] + [1] \]

(それらはすべてあなたのために分かれています)

\([...] \)は、間隔、間隔の数\(O(n)\)と見なされるため、1回限りの問題はありません。間隔とクエリ間隔が交差する場合は、間隔の1回だけ出力してください。最後のインターバルの特別な判断

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll;
#define int ll
int T,n,l,r,rr;
void work(int a,int l,int r){
	int cnt=0;
	repeat(i,a+1,n+1){
		cnt++; if(l<=cnt && cnt<=r)printf("%lld ",a);
		cnt++; if(l<=cnt && cnt<=r)printf("%lld ",i);
	}
}
signed main(){
	cin>>T;
	while(T--){
		cin>>n>>l>>rr; r=min(rr,n*(n-1));
		if(l<=r){
			int x=(n-1)*2;
			while(x<l)l-=x,r-=x,x-=2;
			while(r>0){
				work(n-x/2,l,r);
				l-=x,r-=x;
				x-=2;
			}
		}
		if(rr==n*(n-1)+1)printf("1");
		puts("");
	}
	return 0;
}

E.除数パス

有用なプロパティはすべての数の素因数の中に含まれているである\(D \) 素因数のセット内の\(D \)を超えない30の素因数の数、従って安全に列挙素因数バー/ XYX

穏やかな分析の後、トピックに入ると、\(a_1 \)\(a_2 ... a_ {k-1} \)の\(a_k \)に移動し、その数が途中で厳密に増加している場合、長さは\( d(a_2)-d(a​​_1)+ d(a_3)-d(a​​_2)+ ... + d(a_k)-d(a​​_(k-1))\) \(= d(a_k)-d( a_1)\)\(d(n)\)は、中間ノードに関係なく、\(n \))の因子の数を表します!そして、これが最短経路であると推測できます。最短パスの数、マルチセットの組み合わせの数を思い出すことができます\(\ left(\ begin {array} {c}&X&\\ x_1&...&x_n \ end {array} \ right)= \ dfrac {X!} {\ PROD \ limits_ {I} ^ N-1 =(X_I!)} \) 少し言っている場合、例えば、\(1 \)が来る(\ 12 \)を乗じ、[2,2(\ 、3] \)または\([2,3,2] \)または\([3,2,2] \)で十分なので、答えはパスの長さの階乗を2つの数値の階乗で割って、 3つの数値の階乗を取る、\(ans = \ dfrac {3!} {1!\ Cdot2!} = 3 \)

もちろん、問題は解決されていません。上記の操作で解決できるのは、\(a_1 | a_k \)(または\(a_k | a_1 \)の状況のみです。直感は、パスが\(\ gcd(a_1、a_k)\)を通過することを示しています。問題は、\(a_1 \)から\(\ gcd(a_1、a_k)\)\(\ gcd(a_1、 a_k)\)から\(a_k \)までのパス数は、以前の結論に適用できます。理由まあに関しては、私は十分な証拠はないよ私は行くためにそんなに良い方法を感じていない以上になります

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
const int mod=(0?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
int T,n,l,r,rr;
vector<int> d;
map<int,vector<int>> a;
struct CC{
	static const int N=1010;
	ll fac[N],inv[N];
	CC(){
		fac[0]=1;
		repeat(i,1,N)fac[i]=fac[i-1]*i%mod;
		inv[N-1]=qpow(fac[N-1],mod-2,mod);
		repeat_back(i,0,N-1)inv[i]=inv[i+1]*(i+1)%mod;
	}
}C;
void getdivisor(vector<int> &ans,int n){
	ans.assign(d.size(),0);
	repeat(i,0,d.size())
	while(n%d[i]==0)n/=d[i],ans[i]++;
}
vector<int> X,Y;
signed main(){
	int n=read(),q=read();
	for(int i=2;i*i<=n;i++){
		if(n%i==0)d.push_back(i);
		while(n%i==0)n/=i;
	}
	if(n>1)d.push_back(n);
	while(q--){
		int x=read(),y=read();
		getdivisor(X,x);
		getdivisor(Y,y);
		
		int ans=1,sum=0;
		repeat(i,0,d.size())
		if(X[i]>Y[i])
			ans=ans*C.inv[abs(X[i]-Y[i])]%mod,
			sum+=abs(X[i]-Y[i]);
		ans=ans*C.fac[sum]%mod;
		
		sum=0;
		repeat(i,0,d.size())
		if(X[i]<Y[i])
			ans=ans*C.inv[abs(X[i]-Y[i])]%mod,
			sum+=abs(X[i]-Y[i]);
		ans=ans*C.fac[sum]%mod;
		
		cout<<ans%mod<<endl;
	}
	return 0;
}

おすすめ

転載: www.cnblogs.com/axiomofchoice/p/12677430.html