Educational Codeforces Round 113 (Rated for Div. 2) ABCD(更新ing)

cf地址

又是掉分之旅o.o


A水题

B水题

C 一些特殊情况可以特判(如所有数相同,存在2个以上max的数),然后就是一定存在(max-1)这个数(否则方案数为0),最后答案就是只要存在一个(max-1)放在max后面就可以了。答案n!*(num/num+1),(Num为(max-1)数的多少),可以考虑为max和num个(max-1)都随意放,之后存在(1/num+1)的情况不合法。

点击查看代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<bitset>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#include<map>
 
using namespace std;
const int mod = 998244353;
const int maxn = 200005;
int ad(int x,int y) { x+=y; return (x>=mod?x-mod:x); }
int mu(int x,int y) { return 1ll*x*y%mod; }
int ksm(int a,int b) {
	int ans = 1;
	while(b) {
		if(b&1) {
			ans = mu(ans,a);
		}
		b>>=1;
		a = mu(a,a);
	}
	return ans;
}
 
int fac[maxn],inv[maxn],n,a[maxn];
int getc(int a,int b) {
	return mu(mu(fac[a],inv[a-b]),inv[b]);
}
map<int,int>ma;
int main(){
	fac[0]=1; 
	for(int i=1;i<=200000;i++) fac[i] = mu(fac[i-1],i);
//	inv[200000] = ksm(fac[200000],mod-2);
//	for(int i=200000-1;i>=0;i--) inv[i]=mu(inv[i+1],i+1);
//	printf("%d",getc(5,2));
	int t;
	scanf("%d",&t);
	while(t--) {
		int MX = -1; int SM = -1;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) {
			scanf("%d",&a[i]);
			if(a[i]>=MX) {
				SM = MX; MX = a[i]; 
			} else if(a[i]>SM) {
				SM = a[i];
			}
		}
		if(SM==-1) {
			printf("%d\n",fac[n]);	
			continue;
		}
		int mxsum = 0;
		for(int i=1;i<=n;i++) {
			if(a[i]==MX) mxsum++;
		}
		if(mxsum>=2) {
			printf("%d\n",fac[n]); continue;
		}
		if(MX!=SM+1) {
			puts("0"); continue;
		}
		int num = 0;
		for(int i=1;i<=n;i++) {
			if(a[i]==SM) num++;
		}
		printf("%d\n",mu(fac[n],mu(ksm(num+1,mod-2),num)) );
	}
	return 0;
}

D这道题思路还是比较明显的。对于点在交点一定方便,一对点不方便一定他们同是横or竖上的点(但不同行列)且两个点的另一维度的值中间不隔着另一条线。例如(3,4)与(5,6)他们在线y=4与y=6上那么他们中间不能隔x=4。这样思路就很明显,统计这样的对有多少个就可以了。 

点击查看代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<bitset>
#include<queue>
#include<vector>
#include<map>
#include<cstdio>
#include<cmath>

using namespace std;
#define ll long long
const int maxn = 300005;
int T;
int n,m,k;
int hr[maxn],vt[maxn];
int xmap[1000005],ymap[1000005];
void solve() {
	scanf("%d%d%d",&n,&m,&k); // n vertical m horizon k people
	for(int i=1;i<=n;i++) {
		scanf("%d",&vt[i]); // X
		xmap[vt[i]] = i;
	}
	for(int i=1;i<=m;i++) {
		scanf("%d",&hr[i]); // Y
		ymap[hr[i]] = i;
	}
	ll ans = 0;
	map<int,int>cntx,cnty;
	map<int,map<int,int> >cx2,cy2;
	for(int i=1;i<=k;i++) {
		int x,y; scanf("%d%d",&x,&y);
		if(xmap[x]&&ymap[y]) continue;
		if(xmap[x]) {
			int o = lower_bound(hr+1,hr+1+m,y)-hr;
			ans += cnty[o] - cy2[o][x];
			cnty[o]++; cy2[o][x]++;
		} else {
			int o = lower_bound(vt+1,vt+n+1,x)-vt;
			ans += cntx[o] - cx2[o][y];
			cntx[o]++; cx2[o][y]++;
		}
	}
	for(int i=1;i<=n;i++) {
		xmap[vt[i]] = 0;
	}
	for(int i=1;i<=m;i++) {
		ymap[hr[i]] = 0;
	}
	printf("%lld\n",ans);
}

int main(){
	scanf("%d",&T);
	while(T--) solve();
	return 0;
}

E题人傻了,没看懂题解,后面再做吧。。。

posted @ 2021-09-09 23:03  Newuser233  阅读(42)  评论(0编辑  收藏  举报