有 n n n张图片,第 i i i张图片有 A , B , C , D A,B,C,D A,B,C,D四个元素。
称一张图片是累赘的:有两张图片 x , y x,y x,y,如果 x x x有至少三个元素大于 y y y所对应的三个元素,那个 y y y就是累赘的。
例如 x ( A , B , C , D ) = ( 2 , 3 , 3 , 4 ) , y ( A , B , C , D ) = ( 4 , 2 , 5 , 6 ) x(A,B,C,D)=(2,3,3,4),\ y(A,B,C,D)=(4,2,5,6) x(A,B,C,D)=(2,3,3,4), y(A,B,C,D)=(4,2,5,6),其中 x A > y A , x C > y C , x D > y D x_A>y_A,\ x_C>y_C,\ x_D>y_D xA>yA, xC>yC, xD>yD,那么 y y y就是累赘的。要注意, x x x有可能是累赘的。
输出有多少张累赘的图片 m m m张,接下来 m m m行由小到大输出累赘图片的编号。
1 ≤ n ≤ 1 0 5 1 \le n\le 10^5 1≤n≤105
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
(看着像偏序)
先把每 i i i张图片的四个信息,转化成 4 4 4个信息下 i i i个元素各自的排名。
因为称 y y y图片是累赘的,只需要找到一张图片 x x x存在三个元素大于 y y y所对应的就行,并把 y y y标记为 u l s uls uls的(useless 累赘)。至于是哪一张图片使得 y y y成为累赘的并不重要,这是最关键的。
那么可以四个里面随便钦定三个元素进行比对,那么只需 4 4 4次比对。设为 a , b , c a,b,c a,b,c为比对的元素,考虑“以累赘的视角计算自己怎么被搞成累赘的”。
先按 a a a元素排序,然后在树状数组上,以 b b b元素的排名作为下标,维护一个最小 c c c元素排名值。
听着很抽象啊!
假设当按 a a a元素从小到大排序,所对应的 p o s pos pos为原下标,对应的 b , c b,c b,c属性排名分别是是 b p o s , c p o s b_{pos},c_{pos} bpos,cpos,每次向下标 b p o s b_{pos} bpos加入 c p o s c_{pos} cpos取最小值。
在树状数组上查询 b b b属性排名在 [ 1 , b p o s ) [1,b_{pos}) [1,bpos)的最小 c c c属性的排名记为 m i n c minc minc,此时假设 ∃ p o s ′ , m i n c = c p o s ′ \exist pos',\ minc=c_{pos'} ∃pos′, minc=cpos′。
显然在树状数组上查找,显然 b p o s ′ ∈ [ 1 , b p o s ) , b p o s ′ < b p o s b_{pos'}\in [1,b_{pos}),b_{pos'}
如果 m i n c = c p o s ′ < c p o s minc=c_{pos'}
否则 p o s pos pos就不是累赘的,且 c p o s ≤ c p o s ′ c_{pos}\le c_{pos'} cpos≤cpos′, b p o s b_{pos} bpos下的 c p o s c_{pos} cpos有可能能比“接下来处理的, a a a元素排名肯定比当前 a p o s a_{pos} apos大的, b b b元素排名比 b p o s b_{pos} bpos大的图片 x x x"的 c c c元素要小,使 x x x成为累赘,因此把 p o s pos pos的 c p o s c_{pos} cpos放进树状数组里。
好累啊~~
时间复杂度 Θ ( n log 2 n ) \Theta(n \log_2 n) Θ(nlog2n)
#include
using namespace std;
#define ll long long
const ll N=2e6+9,inf=0x3f3f3f3f;
ll n,m,a[5][N];
bool uls[N];//useless
struct BT
{
ll T[N];
ll lowbit(ll x)
{
return x&(-x);
}
void add(ll x,ll k)
{
for(int i=x;i<N;i+=lowbit(i))
T[i]=min(T[i],k);
}
ll query(ll x)
{
ll ret=inf;
for(int i=x;i>=1;i-=lowbit(i))
ret=min(ret,T[i]);
return ret;
}
}B;
struct node
{
ll rk,id;
}p[N];
bool cmp(node x,node y)
{
return x.rk<y.rk;
}
void sol(ll *a,ll *b,ll *c)
{
memset(B.T,inf,sizeof(B.T));
for(int i=1;i<=n;i++)
p[i]=(node){a[i],i};
sort(p+1,p+n+1,cmp);
for(int i=1;i<=n;i++)
{
ll pos=p[i].id,minc=B.query(b[pos]);
if(c[pos]>minc)uls[pos]=1;
else B.add(b[pos],c[pos]);
}
}
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=4;j++)
scanf("%lld",&a[j][i]);
sol(a[1],a[2],a[3]);
sol(a[1],a[2],a[4]);
sol(a[1],a[3],a[4]);
sol(a[2],a[3],a[4]);
for(int i=1;i<=n;i++)
m+=uls[i];
printf("%lld\n",m);
for(int i=1;i<=n;i++)
if(uls[i])printf("%lld\n",i);
return 0;
}