zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 85 (Div. 2) 题解 (ABCDE)

    比赛链接:https://codeforces.com/contest/1334

    A. Level Statistics

    抓住两个性质,一是游戏次数和通关次数是单调不减的,二是相邻游戏次数的变化量大于等于对应的通关次数变化量

    #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. Middle Class

    财富液化委员会,雾)

    如果把财富倒序排序后,前k个人财富液化后的财富随着k单调不增的,因此for一遍找到最大的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. Circle of Monsters

    先把所有怪的血量降至前一个怪的爆炸伤害以内(如果小于就不用降了),然后for一遍,看看打死第i个怪的额外需要的伤害(因为只要死一个怪就能连环炸死所有怪),取最小

    #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. Minimum Euler Cycle

    如果把 (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)),因此for一遍也没大问题,如果区间和询问区间有相交就在区间内for一遍输出即可,特判最后一个区间

    #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. Divisor Paths

    有一个有用的性质就是所有数的质因数都包含在 (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(egin{array}{c}&X&\x_1&...&x_nend{array} ight)=dfrac{X!}{prodlimits_{i=1}^n(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;
    }
    
  • 相关阅读:
    Leetcode Plus One
    Leetcode Swap Nodes in Pairs
    Leetcode Remove Nth Node From End of List
    leetcode Remove Duplicates from Sorted Array
    leetcode Remove Element
    leetcode Container With Most Water
    leetcode String to Integer (atoi)
    leetcode Palindrome Number
    leetcode Roman to Integer
    leetcode ZigZag Conversion
  • 原文地址:https://www.cnblogs.com/axiomofchoice/p/12677430.html
Copyright © 2011-2022 走看看