Luo Gu solution to a problem SP3267 [DQUERY - D-query]

Mo talked about the team room today.

But konjac I did not understand, so catching up at night to go home, to figure out Mo team.

Mo Team Mo Tao Great God invention, its role is with great complexity of solving the operation between a number of intervals, MO team is actually an elegant violence, its complexity is O (n sqrt (n));

This problem , for example, actually this problem and this problem is the same, but the P1972 will Alcamo team.

Back to this question:

Meaning of the questions is very straightforward, I will not go into details;

1 idea:

Violence, this problem is nothing more than the most simple way to sweep from l to r again, an array count appears next, and then evaluated:

#include<bits/stdc++.h>
using namespace std;
#define maxn 100010
bool flag[maxn];
int n, m, a[maxn], sum, ans, l, r, x, y;
int main()
{
//freopen("count.in","r",stdin);
//freopen("count.out","w",stdout);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i)
scanf("%d", &a[i]);
for(int i = 1; i <= m; ++ i)
{
scanf("%d%d%d%d", &l, &r, &x, &y);
memset(flag, 0, sizeof(flag));
sum = ans = 0;
for(int j = l; j <= r; ++ j)
if(a[j] >= x && a[j] <= y)
{
++ sum;
if(flag[a[j]] == 0)
{
flag[a[j]] = 1;
++ ans;
}
}
printf("%d %d\n", sum, ans);
}
return 0;
}

ans is also desired;

However, this approach is the complexity of O (n * n), and certainly not excessive;

Then you need some optimization:

We use two hands to move the respective constant interval;

int l = 0, r = 1;

Then when moving, we kept add, del;

If it is to the right, to add;

Otherwise, del;

void add(int x)
{
if(cnt[a[x]] == 0)
++ now;
++ cnt[a[x]];
}
void del(int x)
{
-- cnt[a[x]];
if(cnt[a[x]] == 0)
-- now;
}
while(l < q[i].l)
del(l ++);
while(l > q[i].l)
add(-- l);
while(r < q[i].r)
add(++ r);
while(r > q[i].r)
del(r --);

Is this above,

This is the MO team?

No, there is a place,

Let's suppose you want to query interval is [1, 10 million] it?

That is not the same or not optimized.

So Mo team but also a very important place, that sort;

How to sort?

If the left endpoint sort, then the right end point will be well represented;

If you press the right endpoint sort, then the left end point will be well represented;

This time, block Dafa Viva;

The sequence of length n, into sqrt (n) th block;

A row sequence number range according to the query point where the left block, left if the point where the same block, then the right end of the sort.

In fact, konjac I do not understand why this would be faster than 200 ms, but it is the will;

Complexity of the whole process is O (n * sqrt (n));

Time Code:

#include<bits/stdc++.h>
using namespace std;

#define maxn 1000010
int n, m, a[maxn], cnt[maxn], ans[maxn], bein[maxn], l = 1, r, now;

struct node
{
int l, r, id;
}q[maxn];

bool cmp(node a, node b)
{
return bein[a.l] == bein[b.l] ? a.r < b.r : bein[a.l] < bein[b.l];
}

void add(int x)//加入操作 (右移 
{
if(cnt[a[x]] == 0)
++ now;
++ cnt[a[x]];
}

void del(int x)//删除(左移 
{
-- cnt[a[x]];
if(cnt[a[x]] == 0)
-- now;
}

void print(int x)//要从后往前输出,所以来递归输出 
{
if(x / 10)
print(x / 10);
//printf("%d", x % 10);
putchar(x % 10 + '0');
//printf("K"); 
}

int main()
{
scanf("%d", &n);//输入 
for(int i = 1; i <= ceil((double) n / sqrt(n)); ++ i)
for(int j = (i - 1) * sqrt(n) + 1; j <= i * sqrt(n); ++ j)
bein[j] = i;//这是分的块 
for(int i = 1; i <= n; ++ i)
scanf("%d", &a[i]);//还是输入 
scanf("%d", &m);//继续输入 
for(int i = 1; i <= m; ++ i)
{
scanf("%d%d", &q[i].l, &q[i].r);//还要输入 
q[i].id = i;//记录下序号,cmp中要用 
}
sort(q + 1, q + m + 1, cmp);//排序 
/*这种作法就不需要add和del 
for(int i = 1; i <= m; ++i) {
int ql = q[i].l, qr = q[i].r;
while(l < ql) now -= !--cnt[aa[l++]];
while(l > ql) now += !cnt[aa[--l]]++;
while(r < qr) now += !cnt[aa[++r]]++;
while(r > qr) now -= !--cnt[aa[r--]];
ans[q[i].id] = now;
}
*/
for(int i = 1; i <= m; ++ i)
{
while(l < q[i].l)//l右移 
del(l ++);
while(l > q[i].l)//l左移 
add(-- l);
while(r < q[i].r)//r右移 
add(++ r);
while(r > q[i].r)//r左移 
del(r --);
ans[q[i].id] = now;
}
for(int i = 1; i <= m; ++ i)
{
print(ans[i]);//输出 
printf("\n");//记得换行 
}
return 0;
}

Because in this konjac beginning to learn not understand, so there have read WAMonster chiefs article, may be part of the same ideas on, and I strongly recommend the chiefs of the blog, write particularly good.

Guess you like

Origin www.cnblogs.com/Flash-plus/p/12028330.html