跟题解对拍 “找不到差异”
我的程序吸氧能 85pts WA 7,17,19
如下:
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#define ll long long
#define mid (l+r>>1)
#define ls(x) t[x].son[0]
#define rs(x) t[x].son[1]
const int N=8e4+10;
const double alpha=0.7;
const ll mod=998244353;
using namespace std;
inline ll read() {
ll x=0,f=1,c=getchar();
while(c<'0'||c>'9')f=(c=='-'?-1:1),c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
struct Tree {
ll P[4],Min[4],Max[4],val,dp,size,maxn,maxk,Maxk;
int son[2],d;
Tree() {
son[0]=son[1]=0;
d=size=1;
}
void init() {
for(int i=0; i<4; i++)Min[i]=Max[i]=P[i]=read();
dp=maxn=val=read();
}
void clear() {
for(int i=1; i<4; i++)Min[i]=Max[i]=P[i];
son[0]=son[1]=0;
maxn=dp;
Maxk=maxk;
d=size=1;
}
} t[N];
int n,root,D,rub[N],cnt,tot;
inline void update(int x) {
for(int i=1; i<4; i++)t[x].Min[i]=t[x].Max[i]=t[x].P[i];
t[x].maxn=max(t[x].maxn,t[x].dp);
t[x].Maxk=t[x].maxk;
t[x].size=1;
if(ls(x)) {
for(int i=1; i<4; i++) {
t[x].Min[i]=min(t[x].Min[i],t[ls(x)].Min[i]);
t[x].Max[i]=max(t[x].Max[i],t[ls(x)].Max[i]);
}
if(t[x].maxn==t[ls(x)].maxn)t[x].Maxk+=t[ls(x)].Maxk%mod;
if(t[x].maxn<t[ls(x)].maxn) {
t[x].maxn=t[ls(x)].maxn;
t[x].Maxk=t[ls(x)].Maxk;
}
t[x].size+=t[ls(x)].size;
}
if(rs(x)) {
for(int i=1; i<4; i++) {
t[x].Min[i]=min(t[x].Min[i],t[rs(x)].Min[i]);
t[x].Max[i]=max(t[x].Max[i],t[rs(x)].Max[i]);
}
if(t[x].maxn==t[rs(x)].maxn)t[x].Maxk+=t[rs(x)].Maxk%mod;
if(t[x].maxn<t[rs(x)].maxn) {
t[x].maxn=t[rs(x)].maxn;
t[x].Maxk=t[rs(x)].Maxk;
}
t[x].size+=t[rs(x)].size;
}
}
inline bool Cmp(int x,int y) {
return t[x].P[D]<t[y].P[D];
}
inline int build(int l,int r) {
if(l>r)return 0;
double avr[4]= {0},var[4]= {0};
for(int i=l; i<=r; i++)
for(int j=1; j<4; j++)
avr[j]+=t[rub[i]].P[j];
for(int j=1; j<4; j++)avr[j]/=1.0*(r-l+1);
for(int i=l; i<=r; i++)
for(int j=1; j<4; j++)
var[j]+=(t[rub[i]].P[j]-avr[j])*(t[rub[i]].P[j]-avr[j]);
if(max({var[1],var[2],var[3]})==var[1])D=t[rub[mid]].d=1;
if(max({var[1],var[2],var[3]})==var[2])D=t[rub[mid]].d=2;
if(max({var[1],var[2],var[3]})==var[3])D=t[rub[mid]].d=3;
nth_element(rub+l,rub+mid,rub+r+1,Cmp);
ls(rub[mid])=build(l,mid-1);
rs(rub[mid])=build(mid+1,r);
update(rub[mid]);
return rub[mid];
}
inline void Del(int x) {
if(!x)return ;
Del(ls(x)),Del(rs(x));
t[x].clear();
rub[++cnt]=x;
}
inline void rebuild(int &x) {
cnt=0;
Del(x);
x=build(1,cnt);
}
inline bool cmp(Tree a,Tree b) {
for(int i=0; i<4; i++)
if(a.P[i]!=b.P[i])
return a.P[i]<b.P[i];
return 0;
}
inline void Insert(int u,int &x) {
if(!x) {
x=++tot;
update(x);
return;
}
D=t[x].d;
if(t[u].P[D]<t[x].P[D])Insert(u,ls(x));
else Insert(u,rs(x));
update(x);
if(t[x].size*alpha<max(t[ls(x)].size,t[rs(x)].size))rebuild(x);
}
inline void query(int u,int x) {
if(!x)return;
for(int i=1; i<4; i++)
if(t[u].P[i]<t[x].Min[i])
return ;
if(t[x].maxn+t[u].val<t[u].dp)return;
bool flag=1;
for(int i=1; i<4; i++)
if(t[u].P[i]<t[x].P[i])
flag=0;
if(flag) {
if(t[u].dp==(t[x].dp+t[u].val))t[u].maxk+=t[x].maxk%=mod;
if(t[u].dp<(t[x].dp+t[u].val)) {
t[u].dp=t[x].dp+t[u].val;
t[u].maxk=t[x].maxk;
}
}
if(ls(x))query(u,ls(x));
if(rs(x))query(u,rs(x));
}
int main() {
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
n=read(),read();
for(int i=1; i<=n; i++)t[i].init();
sort(t+1,t+n+1,cmp);
for(int i=1; i<=n; i++) {
query(i,root);
if(!t[i].maxk)t[i].maxk=1;
Insert(i,root);
}
ll ans=0;
for(int i=1; i<=n; i++)
ans=max(ans,t[i].dp);
printf("%lld",ans);
ll cur=0;
for(int i=1; i<=n; i++)
if(ans==t[i].dp)
cur+=t[i].maxk;
printf("\n%lld",cur);
return 0;
}