Educational Codeforces Round 113 (Rated for Div. 2) ABCD(更新ing)
又是掉分之旅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题人傻了,没看懂题解,后面再做吧。。。