Draw

题目背景

SOURCE:NOIP2016-RZZ-4 T3

题目描述

给定笛卡尔坐标系上 n 个不重复的点。

定义一个 L 形为:

一个形如 (x,y),(x+1,y)…(x+a,y),(x,y+1)…(x,y+b) 的点集。

并且满足 a,b≥1 且 gcd(a,b)=1。

求有多少个集合的二元组 (A,B) 满足 A 和 B 都是 L 形,且 A 和 B 没有交,即A∩B=φ。其中 A 和 B 是两个集合,A 和 B可以相等。,

当 A≠B 时,我们将 (A,B) 和 (B,A) 视为不同的二元组。

输入格式

第一行一个整数 n 。

接下来 n 行每行两个正整数 xi,yi 描述点的坐标。

输出格式

输出一个整数,表示答案。

样例数据 1

输入

1 1

1 2

2 1

3 3

3 4

4 3

输出

2

备注

【数据规模与约定】

设坐标 xi,yi 的范围为 [1,S]。

对于 30% 的数据,S≤10。

对于 50% 的数据,S≤50。

对于 100% 的数据,S≤200,0≤n≤4*104,n≤S^2。

这题要用玄学的容斥原理,考场上50" role="presentation" style="position: relative;">5050分写挂了。听完评讲发现自己的方法改一下就成正解了。

我们先统计出所有的二元组个数,然后去掉有交集的就行了。那我们来讨论一下有交集的情况。

  • 两个l" role="presentation" style="position: relative;">ll拐点重合:直接算。
  • 两个拐点不在一条水平线或铅直线上,枚举其中一个拐点和其中一条边统计经过边上某点的l" role="presentation" style="position: relative;">ll的数量。
  • 两个拐点在一条水平线或在铅直线上上,类似的方法枚举。

代码(丑)如下:

  1. #include<bits/stdc++.h>
  2. #define D 205
  3. #define N 40005
  4. #define ll long long
  5. using namespace std;
  6. ll num[D][D];
  7. ll cnt[D][D],sum;
  8. ll f[D][D],u[D][D],r[D][D],n,s;
  9. bool mp[D][D];
  10. struct pot{ll x,y;}p[N];
  11. inline ll gcd(ll a,ll b){while(b){ll t=a;a=b,b=t%a;}return a;}
  12. inline ll solve(ll m,ll n){
  13. ll ret=0;
  14. for(ll i=1;i<=n;++i)ret+=(gcd(i,m)==1);
  15. return ret;
  16. }
  17. inline void init(){
  18. memset(num,0,sizeof(num));
  19. for(ll i=1;i<=200;++i)
  20. for(ll j=1;j<=200;++j)
  21. f[i][j]=solve(i,j),num[i][j]=num[i-1][j]+f[i][j];
  22. }
  23. inline ll read(){
  24. ll ans=0;
  25. char ch=getchar();
  26. while(!isdigit(ch))ch=getchar();
  27. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
  28. return ans;
  29. }
  30. int main(){
  31. init();
  32. n=read();
  33. memset(mp,false,sizeof(mp));
  34. memset(u,0,sizeof(u));
  35. memset(r,0,sizeof(r));
  36. memset(cnt,0,sizeof(cnt));
  37. for(ll i=1;i<=n;++i){
  38. p[i].x=read(),p[i].y=read();
  39. mp[p[i].x][p[i].y]=true;
  40. }
  41. for(ll i=200;i>=1;--i)
  42. for(ll j=200;j>=1;--j)
  43. if(mp[i][j]){
  44. if(mp[i][j+1])r[i][j]=r[i][j+1]+1;
  45. if(mp[i+1][j])u[i][j]=u[i+1][j]+1;
  46. }
  47. for(ll i=1;i<=200;++i)
  48. for(ll j=1;j<=200;++j)
  49. if(mp[i][j]){
  50. ll q[D];
  51. memset(q,0,sizeof(q));
  52. for(ll k=1;k<=u[i][j];++k)q[k]=f[k][r[i][j]];
  53. for(ll k=u[i][j];k>=1;--k)q[k-1]+=q[k];
  54. s+=q[0];
  55. for(ll k=0;k<=u[i][j];++k)cnt[i+k][j]+=q[k];
  56. }
  57. ll ans=0;
  58. for(ll i=1;i<200;++i)
  59. for(ll j=1;j<200;++j)
  60. if(u[i][j]&&r[i][j]){
  61. ll tmp=cnt[i][j],redu;
  62. tmp-=(redu=num[u[i][j]][r[i][j]]);
  63. for(ll k=1;k<=r[i][j];++k){
  64. tmp+=cnt[i][j+k];
  65. ans+=f[k][u[i][j]]*tmp*2;
  66. }
  67. ans+=redu*redu;
  68. }
  69. printf("%lld",s*s-ans);
  70. return 0;
  71. }

2018.07.10NOIP模拟 Draw(容斥原理)的更多相关文章

  1. 2018.07.10NOIP模拟 Knapsack(单调队列优化dp)

    Knapsack 题目背景 SOURCE:NOIP2016-RZZ-4 T2 题目描述 有 n 个物品,第 i 个物品的重量为 ai . 设 f(i,j,k,l,m) 为满足以下约束的物品集合数量: ...

  2. 2018.07.26NOIP模拟 魔法数字(数位dp)

    魔法数字 题目背景 ASDFZ-NOIP2016模拟 题目描述 在数论领域中,人们研究的基础莫过于数字的整除关系.一般情况下,我们说整除总在两个数字间进行,例如 a | b(a能整除b)表示 b 除以 ...

  3. China Cloud Computing Conference(2018.07.24)

    时间:2018.07.24地点:北京国家会议中心

  4. AI Summit(2018.07.19)

    AI Summit 时间:2018.07.19地点:北京丽都皇冠假日酒店

  5. China Internet Conference(2018.07.12)

    中国互联网大会 时间:2018.07.12地点:北京国家会议中心

  6. 【2018.06.26NOIP模拟】T3节目parade 【支配树】*

    [2018.06.26NOIP模拟]T3节目parade 题目描述 学校一年一度的学生艺术节开始啦!在这次的艺术节上总共有 N 个节目,并且总共也有 N 个舞台供大家表演.其中第 i 个节目的表演时间 ...

  7. 【2018.06.26NOIP模拟】T2号码bachelor 【数位DP】*

    [2018.06.26NOIP模拟]T2号码bachelor 题目描述 Mike 正在在忙碌地发着各种各样的的短信.旁边的同学 Tom 注意到,Mike 发出短信的接收方手机号码似乎都满足着特别的性质 ...

  8. 【2018.06.26NOIP模拟】T1纪念碑square 【线段树】*

    [2018.06.26NOIP模拟]T1纪念碑square 题目描述 2034年,纪念中学决定修建校庆100周年纪念碑,作为杰出校友的你被找了过来,帮校方确定纪念碑的选址. 纪念中学的土地可以看作是一 ...

  9. 2018.07.13 [HNOI2015]落忆枫音(容斥原理+dp)

    洛谷的传送门 bzoj的传送门 题意简述:在DAG中增加一条有向边,然后询问新图中一共 有多少个不同的子图为"树形图". 解法:容斥原理+dp,先考虑没有环的情况,经过尝试不难发现 ...

随机推荐

  1. JSON解析工具比较,主要GSON和FastJSON

    JSON解析工具比较,主要GSON和FastJSON 一 .各个JSON技术的简介和优劣 1.json-lib json-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确 ...

  2. gevent 实现单线程下的socket链接

    通过gevent实现socket的多并发 server 端: import geventfrom gevent import socket, monkey monkey.patch_all() #进行 ...

  3. ubuntu16.04设置电池充电阈值

    thinkpad在安装ubuntu16.04之后,设置充电阈值: 方法一: 使用双系统,在windows下使用联想的Lenovo setting center设置之后,在ubuntu之下也可以保持相同 ...

  4. ntohs, ntohl, htons,htonl的比较和详解【转】

    ntohs =net to host short int 16位 htons=host to net short int 16位 ntohs =net to host long int 32位 hto ...

  5. redis启动.停止.重启

    Linux下安装 ]# wget http://download.redis.io/releases/redis-2.8.17.tar.gz ]# tar xzf redis-2.8.17.tar.g ...

  6. struts2 自带的 token防止表单重复提交拦截器

    在struts2中,我们可以利用struts2自带的token拦截器轻松实现防止表单重复提交功能! 1. 在相应的action配置中增加:  <interceptor-ref name=&quo ...

  7. hive 显示分区

    显示某一张表的分区值 show partitions table_name;

  8. str和repr的区别(转)

    Python打印值的时候会保持该值在python代码中的状态,不是用户所希望看到的状态.而使用print打印值则不一样,print打印出来的值是用户所希望看到的状态. 例如: >>> ...

  9. Python运维开发基础10-函数基础

    一,函数的非固定参数 1.1 默认参数 在定义形参的时候,提前给形参赋一个固定的值. #代码演示: def test(x,y=2): #形参里有一个默认参数 print (x) print (y) t ...

  10. python中使用Opencv进行人脸检测

    这两天学习了人脸识别,看了学长写的代码,边看边码边理解搞完了一边,再又是自己靠着理解和记忆硬码了一边,感觉还是很生疏,就只能来写个随笔加深一下印象了. 关于人脸识别,首先需要了解的是级联分类器Casc ...