普通莫队
哔哩哔哩
链接: link.
洛谷2709
链接: link.
ac代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 5E4 + 7;
int cnt[maxn], arr[maxn], n, m, k, block; //计数,原数组,总长度,总边数,范围,根块
ll ans[maxn], sum; //存结果,结果指针
struct node
{
int l, r, id;
bool operator<(const node &t) const
{
if (l / block == t.l / block)
return r < t.r;
return l / block < t.l / block;
}
} q[maxn];
void update(int pos, int n)
{
int val = arr[pos];
if (n == 1)
sum = sum + 2 * cnt[val] + 1;
else
sum = sum - 2 * cnt[val] + 1;
cnt[val] += n;
}
int main()
{
cin >> n >> m >> k;
block =sqrt(n);
for (int i = 1; i <= n; i++)
{
cin >> arr[i];
}
for (int i = 1; i <= m; i++)
{
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q + 1, q + 1 + m);
int l = q[1].l;//跗骨之蛆
int r = q[1].l - 1;
for (int i = 1; i <= m; i++)
{
while (l > q[i].l)
update(--l, 1);
while (r < q[i].r)
update(++r, 1);
while (l < q[i].l)
update(l++, -1);
while (r > q[i].r)
update(r--, -1);
ans[q[i].id] = sum;
}
for (int i = 1; i <= m; i++)
cout << ans[i] << "\n";
//system("pause");
}
acw2492
链接: link.
ac代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1E6 + 7;
int n, m, sum, block;
int arr[N], cnt[N];
int ans[N];
struct node
{
int l, r, id;
bool operator<(const node &t) const
{
if (l / block == t.l / block)
return r < t.r;
return l / block < t.l / block;
}
} q[N];
void update(int pos, int n)
{//只有新加的和最后一个退场
int val = arr[pos];
if (n == 1){
if(cnt[val]==0)
sum++;
}
else{
if(cnt[val]==1)
sum--;
}
cnt[val] += n;
}
int main()
{
cin >> n;
block = sqrt(n);
for (int i = 1; i <= n; i++)
cin >> arr[i];
cin >> m;
for (int i = 1; i <= m; i++)
{
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q + 1, q + 1 + m);
int l = q[1].l;
int r = q[1].l - 1;
for (int i = 1; i <= m; i++)
{
while (l > q[i].l)
update(--l, 1);
while (r < q[i].r)
update(++r, 1);
while (l < q[i].l)
update(l++,-1);
while (r > q[i].r)
update(r--,-1);
ans[q[i].id] = sum;
}
for(int i=1;i<=m;i++){
cout << ans[i] << endl;
}
}
树上莫队
带修莫队
acw2521
ac代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1E6 + 7;
int n, m;
int c[N];
struct node1
{
int l, r, x, id;
} q[N];
struct node2
{
int x, y;
} ch[N];
int index1 = 0, index2 = 0, block, ans[N], tot = 0, sum[N];
int cmp(const node1 &a, const node1 &b)
{
if (a.l / block != b.l / block)
return a.l < b.l;
else if (a.r / block != b.r / block)
return a.r < b.r;
else
return a.x < b.x;
}
void update(int wz, int z)
{
if (z == -1)
{
sum[c[wz]]--;
if (!sum[c[wz]])
tot--;
}
else
{
sum[c[wz]]++;
if (sum[c[wz]] == 1)
tot++;
}
}
void change(int bh, int z, int l, int r)
{
if (ch[bh].x >= l && ch[bh].x <= r)
update(ch[bh].x, -1); //删除从前的影响
swap(c[ch[bh].x], ch[bh].y);
if (ch[bh].x >= l && ch[bh].x <= r)
update(ch[bh].x, 1); //添加影响
}
void solve()
{
int l = 1, r = 0, now = 0;
for (int i = 1; i <= m; i++)
{
while (r < q[i].r)
update(r + 1, 1), r++;
while (r > q[i].r)
update(r, -1), r--;
while (l > q[i].l)
update(l - 1, 1), l--;
while (l < q[i].l)
update(l, -1), l++;
while (now < q[i].x)
change(now + 1, 1, l, r), now++;
while (now > q[i].x)
change(now, -1, l, r), now--;
ans[q[i].id] = tot;
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &c[i]);
for (int i = 1; i <= m; i++)
{
char s[2];
int x, y;
scanf("%s%d%d", &s, &x, &y);
if (s[0] == 'Q')
{
index1++;
q[index1].l = x;
q[index1].r = y;
q[index1].x = index2;
q[index1].id = index1;
}
else
{
index2++;
ch[index2].x = x;
ch[index2].y = y;
}
}
block = (int)pow(n, 0.666666);
sort(q + 1, q + 1 + index1, cmp);
solve();
for (int i = 1; i <= index1; i++)
printf("%d\n", ans[i]);
return 0;
}