数三角形 bzoj 1201
数三角形
【题目描述】
小苏看到一个这样的等边三角形:该等边三角形每边的长度为n且被分成n等份,于是每条边就有n-1个等分点。而整个三角形被连接两个不同边的等分点且平行于三角形的第三边的线段分成了n2个单位等边三角形(边长为1)。下图左是n=5的情形:

小苏想知道,删除其中的一些短边后,剩下的边一共组成多少个三角形(包括所有边长为m的三角形),正立的和倒立的都算,只要三角形的3m条短边都没有被删除就算是组成一个三角形)。例如,上图右就存在19个三角形。
【输入格式】
大三角形的所有短边可以看成由(n+1)*n/2个单位三角形的边界组成。如下图的灰色三角形所示。其中第1排有1个灰色三角形,第2排有2个灰色三角形,……,第n排有n个灰色三角形。所以输入格式是这样规定的:

从文件中读入数据,文件第一行为正整数n,表示大三角形每边的长度。接下来的n行,第i+1行有i组数,从左到右每组数描述一个三角形,每组数都有3个数,这3个数非0即1,表示对应的短边是否被删除,0表示已被删除,1表示未被删除,依次按照三角形的左、右、下边的顺序来描述。所以第i+1行有3i个数,每个数是0或1。
【输出格式】
输出文件中仅包含一个整数T,表示有多少个三角形的边界都没有被删除。
【输入样例】
5
1 1 1
1 1 0 1 1 0
1 1 1 1 1 1 1 0 1
1 0 1 1 1 1 0 1 1 1 1 1
0 1 1 1 1 1 0 1 1 1 1 1 0 1 1
【输出样例】
19
【数据范围】
1<=n<=1000,1<=m<=n。
题解:
先考虑正三角,枚举底边所在的直线,一个合法三角形的底边是实线,左右两边比底边长
预处理:
c[i].l : 往左上延伸的最长长度
c[i].r : 往右上延伸的最长长度
r[i] : 向右延伸的最长长度
设一条底边的两个编号为 i 和 j
那么一个合法三角形需要满足:
(1)点 i 在点 j 的左边 : i < j -> i >= j
(2)i 到 j 之间为实边: r[i] >= j
(3)左边长于底边 : j - i <= c[i].r -> c[i].r + i >= j
(4)右边长于底边 : j - i <= c[j].l -> i >= j + c[j].l
那么转化为了关于 j 的不等式组
然后将 j 按 j - c[j].l 排序
从大到小枚举 i ,在树状数组中加入满足(4)的点 j
那么答案就是满足 (2) 和 (3) 的元素个数中的较小值减去转化过的条件(1)的元素个数
其实暴力能过(* ̄^ ̄(* ̄^ ̄(* ̄^ ̄)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
inline int Get()
{
int x = ;
char c = getchar();
while('' > c || c > '') c = getchar();
while('' <= c && c <= '')
{
x = (x << ) + (x << ) + c - '';
c = getchar();
}
return x;
}
struct shape
{
int l, r, m;
};
struct mystery
{
int v, i;
};
shape a[][], c[][];
mystery s[];
int n;
int ans;
int r[][];
int tr[];
inline void Add(int x, int y)
{
while(x <= n + )
{
tr[x] += y;
x += x & (-x);
}
}
inline int Sum(int x)
{
int sum = ;
while(x)
{
sum += tr[x];
x -= x & (-x);
}
return sum;
}
inline bool rule(mystery a, mystery b)
{
if(a.v != b.v) return a.v < b.v;
return a.i < b.i;
}
inline void Up()
{
for(int i = ; i <= n; ++i)
{
for(int j = ; j <= i + ; ++j)
{
if(!a[i][j].l) c[i][j].r = ;
else c[i][j].r = c[i - ][j].r + ;
if(!a[i][j - ].r) c[i][j].l = ;
else c[i][j].l = c[i - ][j - ].l + ;
}
for(int j = i + ; j >= ; --j)
{
if(!a[i][j].m) r[i][j] = j;
else r[i][j] = r[i][j + ];
}
}
for(int k = ; k <= n; ++k)
{
for(int i = ; i <= k + ; ++i)
{
s[i].v = i - c[k][i].l;
s[i].i = i;
}
sort(s + , s + + k + , rule);
int num = ;
for(int i = ; i <= k + ; ++i)
{
while(num <= k + && s[num].v <= i)
{
Add(s[num].i, );
++num;
}
if(c[k][i].r && r[k][i])
{
int one = Sum(c[k][i].r + i);
int two = Sum(i);
int thr = Sum(r[k][i]);
ans += min(one, thr) - two;
}
}
for(int i = ; i < num; ++i) Add(s[i].i, -);
}
}
inline void Down()
{
for(int i = n; i >= ; --i)
{
for(int j = ; j <= i; ++j)
{
if(!a[i][j].r) c[i][j].r = ;
else c[i][j].r = c[i + ][j + ].r + ;
if(!a[i][j].l) c[i][j].l = ;
else c[i][j].l = c[i + ][j].l + ;
}
for(int j = i; j >= ; --j)
{
if(!a[i - ][j].m) r[i][j] = j;
else r[i][j] = r[i][j + ];
}
}
for(int k = ; k <= n; ++k)
{
for(int i = ; i <= k; ++i)
{
s[i].v = i - c[k][i].l;
s[i].i = i;
}
sort(s + , s + + k, rule);
int num = ;
for(int i = ; i <= k; ++i)
{
while(num <= k && s[num].v <= i)
{
Add(s[num].i, );
++num;
} if(c[k][i].r && r[k][i])
{
int one = Sum(c[k][i].r + i);
int two = Sum(i);
int thr = Sum(r[k][i]);
ans += min(one, thr) - two;
}
}
for(int i = ; i < num; ++i) Add(s[i].i, -);
}
}
int main()
{
n = Get();
for(int i = ; i <= n; ++i)
for(int j = ; j <= i; ++j)
{
a[i][j].l = Get();
a[i][j].r = Get();
a[i][j].m = Get();
}
Up();
Down();
printf("%d", ans);
}
数三角形 bzoj 1201的更多相关文章
- 1201: [HNOI2005]数三角形 - BZOJ
Description Input 大三角形的所有短边可以看成由(n+1)*n/2个单位三角形的边界组成.如下图的灰色三角形所示.其中第1排有1个灰色三角形,第2排有2个灰色三角形,……,第n排有n个 ...
- [CQOI 2014] 数三角形 & 机械排序臂
数三角形 bzoj 3505 要知道一个公式就是(a,b)和(x,y)两点所成线段上面的整点数是gcd(a-x,b-y)-1,通过枚举原点到map上任意一点所能成的三角形,再平移,得到要去掉的三点共线 ...
- bzoj 1201[HNOI2005]数三角形 1202 [HNOI2005]狡猾的商人 暴力 权值并查集
[HNOI2005]数三角形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 349 Solved: 234[Submit][Status][Disc ...
- BZOJ 3505: [Cqoi2014]数三角形 数学
3505: [Cqoi2014]数三角形 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形 容斥
1914: [Usaco2010 OPen]Triangle Counting 数三角形 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 272 Sol ...
- Bzoj 3505: [Cqoi2014]数三角形 数论
3505: [Cqoi2014]数三角形 Time Limits: 1000 ms Memory Limits: 524288 KB Detailed Limits Description
- bzoj 3505: [Cqoi2014]数三角形 组合数学
3505: [Cqoi2014]数三角形 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 478 Solved: 293[Submit][Status ...
- BZOJ 3505: [Cqoi2014]数三角形( 组合数 )
先n++, m++ 显然答案就是C(3, n*m) - m*C(3, n) - n*C(3, m) - cnt. 表示在全部点中选出3个的方案减去不合法的, 同一行/列的不合法方案很好求, 对角线的不 ...
- BZOJ 3505: [Cqoi2014]数三角形 [组合计数]
3505: [Cqoi2014]数三角形 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个. 注意三角形的三点不能共线. 1<=m,n<=1000 $n++ m++$ $ans ...
随机推荐
- 【Paddy】如何将物理表分割成动态数据表与静态数据表
前言 一般来说,物理表的增.删.改.查都受到数据量的制约,进而影响了性能. 很多情况下,你所负责的业务关键表中,每日变动的数据库与不变动的数据量比较,相差非常大. 这里我们将变动的数据称为动态数据,不 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (39) ------ 第七章 使用对象服务之配置模型和使用单复数服务
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-3 配置模型 问题 你想了解配置模型中的各种选项. 解决方案 当你添加一个AD ...
- salesforce 零基础学习(四十四)实现checkbox列表简单过滤功能
现在做的项目代码是原来其他公司做的,要在原来基础上业务进行适当调整加上一些CR,其中有一个需要调整的需求如下: 原来使用apex:selectCheckboxes封装了一个checkbox列表,因为数 ...
- VMWare vSphere Client 克隆虚拟机 更改IP
克隆虚拟机后,查看该虚拟机所分配的MAC地址. 打开控制台,进入linux界面. 打开/etc/udev/rules.d/70-persistent-net.rules内容如下面例子所示: # vi ...
- sizzle分析记录:分解流程
<form> <label>Name:</label> <input name="name" /> <fieldset> ...
- OpenCASCADE Conic to BSpline Curves-Parabola
OpenCASCADE Conic to BSpline Curves-Parabola eryar@163.com Abstract. Rational Bezier Curve can repre ...
- .NET平台开源项目速览(11)KwCombinatorics排列组合使用案例(1)
今年上半年,我在KwCombinatorics系列文章中,重点介绍了KwCombinatorics组件的使用情况,其实这个组件我5年前就开始用了,非常方便,麻雀虽小五脏俱全.所以一直非常喜欢,才写了几 ...
- Apache漏洞修复
今天受同事的委托,修复一台服务器的Apache漏洞,主要集中在以下几点: 1.Apache httpd remote denial of service(中危) 修复建议:将Apache HTTP S ...
- 触屏touch事件记录
一.chrome中的Remote Debugging 一开始并没有用这个调试,不过后面需要多点触碰,可chrome模拟器中我没看到这个功能.突然看到了Remote Debugging,网站需要FQ才能 ...
- unbuntu14.04 安装nginx配置
记录一下linux下安装nginx的所需要的配置. 首先从 nginx官网 下载所需要的版本,复制链接,执行 wget http://nginx.org/download/nginx-1.8.0.ta ...