AtCoder Beginner Contest 127 EF
https://atcoder.jp/contests/abc127
F题:
题意:
有函数f(x)初始为0,有两个操作,
1是给f(x)加上|x−a|+b,
2是询问函数的最小值及x
思路:
查询的时候,b累加就好了,前面就是多个绝对值的函数这样
|x - a1| + |x - a2| + |x - a3|这样 ,想到就是数轴上x到点的距离,就比较清晰了。就是对顶堆有点忘了稍微复习了下。
int t,n,m;
priority_queue<int> down;
priority_queue<int,vector<int>,greater<int>> up;
int main(){
scanf("%d",&n);
int op,a,b;
ll tmpb = 0;
ll downsum = 0,upsum = 0;
for(int i=1;i<=n;i++){
scanf("%d",&op);
if(op == 1){
scanf("%d%d",&a,&b);
if(down.empty() || a <= down.top()) down.push(a),downsum += a;
else up.push(a),upsum += a;
if(down.size() > up.size() + 1) {
up.push(down.top());
downsum -= (int)down.top();
upsum += (int)down.top();
down.pop();
}
if(up.size() > down.size()) {
down.push(up.top());
upsum -= (int)up.top();
downsum += (int)up.top();
up.pop();
}
tmpb += b;
}else{
ll res;
int cnt = down.size() + up.size();
printf("%d ",down.top());
if(cnt & 1){
res = upsum - downsum + down.top() + tmpb;
}else{
res = upsum - downsum + tmpb;
}
printf("%lld\n", res);
}
}
return 0;
}
E题
题意:
求一个n*m网格图里每次选k个格,然后计算这k个格子里任两个曼哈顿距离之和。算出以上所有不同方案答案距离总和
思路:
选k个格子方案数是C(n,m),然后k个格子任两个欧几里得距离有C(k,2)
N×M 的网格图里面任意两点的曼哈顿距离的平均值是(n+m) / 3
答案 =
const ll mod = 1e9+7;
ll t,n,m,k;
ll fac[N],inv[N];
ll qmi(ll a,ll b){
ll res = 1;
while(b){
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
ll C(ll x,ll y){
return fac[x] * inv[y] % mod * inv[x-y] % mod;
}
int main(){
fac[0] = 1;
inv[0] = qmi(fac[0],mod-2);
for(int i=1;i<=200000;i++){
fac[i] = fac[i-1] * i % mod;
inv[i] = qmi(fac[i],mod - 2);
}
cin>>n>>m>>k;
ll res = C(n*m,k) * C(k,2) % mod * (n + m) % mod * qmi(3,mod-2) % mod;
cout<<res<<endl;
return 0;
}