I love counting
O{Mlog?aMAX(B+N/B)}O\{M\log{a_{\text{MAX}}}(\text{B+N/B})\}O{MlogaMAX?(B+N/B)}
md考場寫的莫隊+Trie一直T
#include<bits/stdc++.h>
using namespace std
;
using ll
=long long;
using pii
=pair
<int,int>;
using pli
=pair
<ll
,int>;
constexpr ll mod
=1e9+7;
int rd()
{int res
=0;char ch
=getchar();while(!isdigit(ch
)) ch
=getchar();while( isdigit(ch
)) res
=(res
<<1)+(res
<<3)+(ch
^48),ch
=getchar();return res
;
}
const int N
=100010;
int mp
[N
];
struct node
{int l
,r
;int v
;
}tree
[N
*40];int cnt
;
int ans
[N
],Bs
;
void insert(int x
)
{if(mp
[x
]!=0) return;mp
[x
]++;int u
=0;for(int i
=17;i
>=0;i
--) {int t
=x
>>i
&1;if(t
==0){if(!tree
[u
].l
) tree
[u
].l
=++cnt
;u
=tree
[u
].l
;}else{if(!tree
[u
].r
) tree
[u
].r
=++cnt
;u
=tree
[u
].r
;}if(u
) tree
[u
].v
++;}
}
void del(int x
)
{if(mp
[x
]==0) return;mp
[x
]--;int u
=0;for(int i
=17;i
>=0;i
--) {int t
=x
>>i
&1;if(t
==0)u
=tree
[u
].l
;elseu
=tree
[u
].r
;if(u
) tree
[u
].v
--;}
}
int query(int a
,int b
)
{int res
=0,u
=0;for(int i
=17;i
>=0;i
--){int ai
=a
>>i
&1;int bi
=b
>>i
&1;if(bi
==1) {if(ai
==0) res
+=tree
[tree
[u
].l
].v
;else res
+=tree
[tree
[u
].r
].v
;if(ai
==0) u
=tree
[u
].r
;else u
=tree
[u
].l
;}else{if(ai
==0) u
=tree
[u
].l
;else u
=tree
[u
].r
;}if(!u
) return res
;}return res
+tree
[u
].v
;
}
int pos
[N
];
int A
[N
],n
,m
;
struct nodeq
{int l
,r
;int a
,b
,id
;bool operator<(const nodeq
&o
)const{if(pos
[l
]==pos
[o
.l
]){if(pos
[l
]&1)return r
<o
.r
;else return r
>o
.r
;}return pos
[l
]<pos
[o
.l
];}
}q
[N
];
int main()
{n
=rd();for(int i
=1;i
<=n
;i
++) A
[i
]=rd();m
=rd();for(int i
=1;i
<=m
;i
++){int l
=rd(),r
=rd(),a
=rd(),b
=rd();q
[i
]={l
,r
,a
,b
,i
};}Bs
=sqrt(n
)+1;for(int i
=1;i
<=n
;i
++) pos
[i
]=(i
-1)/Bs
+1;sort(q
+1,q
+1+m
);for(int i
=q
[1].l
;i
<=q
[1].r
;i
++) insert(A
[i
]);ans
[q
[1].id
]=query(q
[1].a
,q
[1].b
);int l
=q
[1].l
,r
=q
[1].r
;for(int i
=1;i
<=m
;i
++){while(l
<q
[i
].l
) del(A
[l
++]);while(r
>q
[i
].r
) del(A
[r
--]);while(r
<q
[i
].r
) insert(A
[++r
]);while(l
>q
[i
].l
) insert(A
[--l
]);ans
[q
[i
].id
]=query(q
[i
].a
,q
[i
].b
);}for(int i
=1;i
<=m
;i
++) printf("%d\n",ans
[i
]);return 0;
}
Code2
O(Mlog?Nlog?aMAX)O(M\log{N}\log{a_{\text{MAX}}})O(MlogNlogaMAX?)
和第一場一樣,樹狀數組套Trie
#include<bits/stdc++.h>
using namespace std
;
using ll
=long long;
using pii
=pair
<int,int>;
using pli
=pair
<ll
,int>;
constexpr ll mod
=1e9+7;
int rd()
{int res
=0;char ch
=getchar();while(!isdigit(ch
)) ch
=getchar();while( isdigit(ch
)) res
=(res
<<1)+(res
<<3)+(ch
^48),ch
=getchar();return res
;
}
const int N
=100010;
struct node
{int l
,r
;int v
;
}tree
[N
*400];
int rt
[N
],cnt
;
void insert(int &p
,int x
)
{if(!p
) p
=++cnt
;int u
=p
;for(int i
=17;i
>=0;i
--) {int t
=x
>>i
&1;if(t
==0){if(!tree
[u
].l
) tree
[u
].l
=++cnt
;u
=tree
[u
].l
;}else{if(!tree
[u
].r
) tree
[u
].r
=++cnt
;u
=tree
[u
].r
;}if(u
) tree
[u
].v
++;}
}
void del(int u
,int x
)
{if(!u
) return;for(int i
=17;i
>=0;i
--) {int t
=x
>>i
&1;if(t
==0)u
=tree
[u
].l
;elseu
=tree
[u
].r
;if(u
) tree
[u
].v
--;}
}
int query(int u
,int a
,int b
)
{int res
=0;if(!u
) return 0;for(int i
=17;i
>=0;i
--){int ai
=a
>>i
&1;int bi
=b
>>i
&1;if(bi
==1) {if(ai
==0) res
+=tree
[tree
[u
].l
].v
;else res
+=tree
[tree
[u
].r
].v
;if(ai
==0) u
=tree
[u
].r
;else u
=tree
[u
].l
;}else{if(ai
==0) u
=tree
[u
].l
;else u
=tree
[u
].r
;}if(!u
) return res
;}return res
+tree
[u
].v
;
}
int A
[N
],n
,m
;
int last
[N
];
int lowbit(int x
){return x
&-x
;}
void Add(int k
,int x
){for(;k
<=n
;k
+=lowbit(k
))insert(rt
[k
],x
);}
void Sub(int k
,int x
){for(;k
<=n
;k
+=lowbit(k
))del(rt
[k
],x
);}int ask(int k
,int a
,int b
)
{int res
=0;for(;k
;k
-=lowbit(k
)) res
+=query(rt
[k
],a
,b
);return res
;
}
struct nodeq
{int l
,a
,b
,id
;
};
vector
<nodeq
> q
[N
];
int ans
[N
];
int main()
{n
=rd();for(int i
=1;i
<=n
;i
++) A
[i
]=rd();m
=rd();for(int i
=1;i
<=m
;i
++){int l
=rd(),r
=rd(),a
=rd(),b
=rd();q
[r
].push_back({l
,a
,b
,i
});}for(int i
=1;i
<=n
;i
++){if(last
[A
[i
]]) Sub(last
[A
[i
]],A
[i
]);Add(i
,A
[i
]);last
[A
[i
]]=i
;for(auto t
:q
[i
]) ans
[t
.id
]=ask(i
,t
.a
,t
.b
)-ask(t
.l
-1,t
.a
,t
.b
);}for(int i
=1;i
<=m
;i
++) printf("%d\n",ans
[i
]);return 0;
}
總結
以上是生活随笔為你收集整理的2021“MINIEYE杯”中国大学生算法设计超级联赛(2)I love counting(Trie树)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。