Subject to the effect:
Topic links:
Luo Gu: https://www.luogu.org/problemnew/show/P1972
BZOJ: https://www.lydsy.com/JudgeOnline/problem.php?id=1878
A given sequence of query How many different numbers.
Ideas:
Mo Bare team title. In fact, this question is a weaker version (without modification)
but this question Alcamo right. open
will MLE.
Do not talk about the team method, I believe we will. Here to talk about how the team card with Mo over this question.
- Input Output Optimization
- Block length
- Merge statement.
This can greatly improve the efficiency of the program.In addition to the code are okay wind ugly accident
So far the program can be snapped into the
. Mo is the most original team
is.
Really do not know how to cut. So Mo had looked at the card team code.
They find that sort of no avail
, but staged this
bool operator < (const Ask &a,const Ask &b){
return pos[a.l]^pos[b.l] ? a.l<b.l : pos[a.l]&1 ? a.r<b.r:a.r>b.r;
}
Seen from the conditional statement, this apparently is in place
a.
And can greatly speed up. I do not know the specific reasons
.
- Plus the metaphysics optimization.
- Luo open valley comes .
This can be very stable over this question out of.
We can see the slowest point inside, considered a fast.
Code:
// luogu-judger-enable-o2
#include <cmath>
#include <ctime>
#include <cstdio>
#include <string>
#include <algorithm>
#define reg register
using namespace std;
const int N=500010,M=1000010;
int n,m,l,r,sum,T,a[N],cnt[M],pos[N],ans[N];
struct Ask
{
int l,r,id;
}ask[N];
bool operator < (const Ask &a,const Ask &b)
{
return pos[a.l]^pos[b.l] ? a.l<b.l : pos[a.l]&1 ? a.r<b.r:a.r>b.r;
}
inline int read()
{
int d=0;
char ch=getchar();
while (!isdigit(ch)) ch=getchar();
while (isdigit(ch))
d=(d<<3)+(d<<1)+ch-48,ch=getchar();
return d;
}
inline void write(int x)
{
if (x>9) write(x/10);
putchar(x%10+48);
}
int main()
{
n=read();
T=1250;
for (reg int i=1;i<=n;++i)
{
a[i]=read();
pos[i]=(i-1)/T+1;
}
m=read();
for (reg int i=1;i<=m;++i)
{
ask[i].l=read(); ask[i].r=read();
ask[i].id=i;
}
sort(ask+1,ask+1+m);
l=1;
for (reg int i=1;i<=m;++i)
{
while(l>ask[i].l) sum+=(++cnt[a[--l]]==1);
while(l<ask[i].l) sum-=(--cnt[a[l++]]==0);
while(r>ask[i].r) sum-=(--cnt[a[r--]]==0);
while(r<ask[i].r) sum+=(++cnt[a[++r]]==1);
ans[ask[i].id]=sum;
}
for (reg int i=1;i<=m;++i)
write(ans[i]),putchar(10);
return 0;
}