【树状数组】指纹
题目描述
随着科技的高速发展,当今很多企业向社会推出了越来越多的结合指纹识别技术的高科技产品。其中以需要进行身份验证或身份识别类型的产品居多,如门禁系统、手提电脑,指纹硬盘等。
对于任何生物识别系统来说,输入数据的质量对于系统准确率有着重大的影响。为了获得较高质量的指纹图像,近年来指纹采集设备不断的被更新,各种先进的指纹采集技术也逐渐被引入到实际产品中。然而尽管如此,由于手指皮肤情况、空气湿度、灰尘等一些因素的影响,依旧存在着大量的质量不高的指纹图像。
通常我们可以通过编号为ABCD 的四个属性来评估一个指纹图像的质量的高低:A)杂点的数量;B)折痕的数量:C)脊线断续程度;D)脊线粘连程度。这四个属性值越小表示该图像在相应方面表现越优。图1 分别示例了这四种属性值较大的时候所形成的指纹图像噪音。
图1 不同类型的指纹噪音
由于指纹图像质量评估研究的需要,我们通过对一个人的指纹进行多次采样后得到多个不同质量的指纹图像,并将其各质量属性记录在一个数据库里面(不同图像的各属值均不相同)。对于两个指纹图像,单个属性的好坏并不能说明图像质量的高低。比如图像1 杂点数比图像2的少,但有可能图像1的粘连程度比图像2高得多,因此我们不能武断的认为图像1就比图像2好。
但是如果一个图像有不少于三个属性都优于另一个图像,那么我们有理由相信前者的质量要优于后者。对于数据库中的一个指纹图像I,如果存在另一个图像J , J 有不少于三个质量属性优于图像I,那么我们认为图像I是一种‘累赘’。
为了减少指纹图像数据库的大小,我们希望去除其中的累赘图像,现在实验室需要你的帮忙,找出该部分图像。为方便计算,我们已经分别按四个属性,计算出了所有图片按该属性的优劣程度排序的名次。
输入
输入文件只有一组数据。
第一行包含一个正整数N,表示有N张指纹图像,编号分别为1,2, … ,N。接下来的N行,每行有4个正整数ai , bi , ci , di。第i行表示编号为i的指纹图像在所有图像中,其A属性排名为ai , B属性排名为bi , C属性排名为ci , D属性排名为di。所有ai 取遍1 到N这N个自然数,1表示最优,N表示最差。类似的,bi ,ci和di也一样。
输出
输出文件第1 行包含一个整数M ,表示累赘的指纹图像个数。接下来M 行,每行包含一个整数,表示累赘的图片的编号。编号从小到大输出。
输入样例
6
1 1 2 6
2 3 3 4
3 4 1 3
4 2 6 5
5 6 5 1
6 5 4 2
输出样例
4
2
4
5
6
数据范围限制
对于20 %的数据,N <=3000 ;
对于所有数据,N <=1000000
题目大意
每个指纹图片有四个属性,如果一个指纹图片有大于等于三个属性劣于任意一其它指纹图片,那么这个图片称为“累赘”。给出每个指纹图片的优劣排名,求出累赘的数量,并从小到大输出累赘的编号。
思路
这道题是一道树状数组题。那么,这道题是怎么和树状数组扯上关系的呢?
如果一个指纹图片的第1、2、3或1、2、4或1、3、4或2、3、4个属性劣于另一个指纹图片,那么这个图片就是累赘。所以,最能让人想到的方法是暴力,每两个图片一一比较这4种情况,最坏时间复杂度为O(4n2)(当数据为随机数的时候,暴力甚至比正解更优,想一想,为什么)。
暴力2:我们先比较1、2、3属性。首先,我们按第一个属性从小到大排序。由于排名不超过1000000,所以我们可以用桶排。a[i][j]为第i个图片的第j个属性的排名。对于任意一图片k,令f[a[j][2]]=a[j][3](1<=j<k),如果min(f[i](i<a[k][2]))<a[k][3],则k就是累赘。因为,属性1已经进行排序,所以,对于任意一图片k,a[j][1]<a[k][1](1<=j<k),如果对于所有a[j][2]<a[k][2]的j,有一a[j][3]<a[k][3],则k必为累赘。我们可以用一个标记数组来标记累赘。比较1、2、4和1、3、4和2、3、4属性类似。时间复杂度为O(n2)。
正解:由min(f[i](i<a[k][2]))<a[k][3]中的min(f[i](i<a[k][2])),我们很容易联想到前缀最小值,由于f数组是有改动的,我们可以用树状树组来求解(不能用st)。最坏时间复杂度为O(n log n)。
代码
#include<cstdio>
#define min(u,v) u<v?u:v
#define lowbit(x) x&-x
int a[1000005][5],f[1000005],c[1000005][</