CF650A Watchmen(STL+map)

7 篇文章 0 订阅


CF650A Watchmen


只有三个map的一篇题解


1. 手推公式

∣ x 2 − x 1 ∣ + ∣ y 2 − y 1 ∣ = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 |x2-x1|+|y2-y1|=\sqrt{(x2-x1)^2+(y2-y1)^2} x2x1+y2y1=(x2x1)2+(y2y1)2

设|x2-x1|=a,|y2-y1|=b

a + b = a 2 + b 2 a+b=\sqrt{a^2+b^2} a+b=a2+b2

( a + b ) 2 = a 2 + b 2 (a+b)^2=a^2+b^2 (a+b)2=a2+b2

a 2 + 2 a b + b 2 = a 2 + b 2 a^2+2ab+b^2=a^2+b^2 a2+2ab+b2=a2+b2

2 a b = 0 2ab=0 2ab=0

a b = 0 ab=0 ab=0

∣ x 2 − x 1 ∣ ∗ ∣ y 2 − y 1 ∣ = 0 |x2-x1|*|y2-y1|=0 x2x1y2y1=0

∣ x 2 − x 1 ∣ = 0    o r    ∣ y 2 − y 1 ∣ = 0 |x2-x1|=0\:\:or\:\:|y2-y1|=0 x2x1=0ory2y1=0

x 1 = x 2    o r    y 1 = y 2 x1=x2\:\:or\:\:y1=y2 x1=x2ory1=y2


2.算法

由公式可知,横纵坐标二选一相同时,两点符合要求

坐标值域很大,可以直接上map

X[]存某行出现过点数,Y[]存某列出现过的点数,p[][]存某个坐标出现过的点数

X[x]+Y[y]-p[x][y]就是答案


3.优化

众所周知,map复杂度是log级的,而unordered_map是O(1)的

所以对于两个下标是int的我们可以用unordered_map代替


4.补充

make_pair(x,y)的意思是将x,y搞成一个pair<,>型东西

以下两段代码等价:

a=make_pair(x,y);
a.first=x;
a.second=y;

(tips.因为CF的c++版本很高,所以要去掉斜杠那两句话,但NOIP中要加上)

#include <bits/stdc++.h>
//#include <tr1/unordered_map>
//using namespace std::tr1;
using namespace std;
unordered_map<int,int> X,Y;
map<pair<int,int>,int> p;
long long ans; //答案会爆int
int n;
signed main(){
    scanf("%d",&n);
    for(int i=1,x,y;i<=n;i++){
        scanf("%d%d",&x,&y);
        ans+=X[x]+Y[y]-p[make_pair(x,y)];
        X[x]++;
        Y[y]++;
        p[make_pair(x,y)]++;
    }
    printf("%I64d",ans);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值