具体差异是update函数和change函数
80分的代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define pii pair<int,int>
#define pll pair<long,long>
#define ls(k) (k*2) //抽象点的
#define rs(k) (k*2+1)
#define all(x) (x).begin(), (x).end()
#define do_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
using namespace std; void run() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); }
#define endl "\n"
// /**/ #define endl "\n\n"
const int N = 1e7 + 10;
const int M = 1e6 + 10;
int root[M], a[M];
struct SegmentTreeNode
{
int L = 0, R = 0, sum = 0;
}tr[M << 5];
int cnt = 0, n, m;
int bt(int pl, int pr)
{ //pl==pr也是在这里编号了
int rt = ++cnt; //为当前树的编号
tr[rt].sum = 0; //sum是统计数量
if (pl == pr)return rt;
int mid = pl + pr >> 1;
tr[rt].L = bt(pl, mid);
tr[rt].R = bt(mid + 1, pr);
return rt;
}
int update(int p, int pl, int pr, int num)
{
int rt = ++cnt;
tr[rt] = tr[p];
tr[rt].sum = tr[p].sum + 1;
if (pl == pr)
return rt;
int mid = (pl + pr) >> 1;
if (num <= mid)
tr[rt].L = update(tr[p].L, pl, mid, num);
if (num > mid)
tr[rt].R = update(tr[p].R, mid + 1, pr, num);
return rt;
}
int change(int p, int pl, int pr, int x)
{
int rt = cnt++;
tr[rt] = tr[p];
tr[rt].sum = tr[p].sum + 1;
if (pl == pr)
return rt;
int mid = pl + pr >> 1;
if (x <= mid)
tr[rt].L = change(tr[p].L, pl, mid, x);
if (x > mid)
tr[rt].R = change(tr[p].R, mid + 1, pr, x);
return rt;
}
int ask(int pl, int pr, int x, int y, int num)
{
if (pl == pr)
return tr[y].sum - tr[x].sum;
int mid = (pl + pr) >> 1;
if (num <= mid)
return ask(pl, mid, tr[x].L, tr[y].L, num);
if (num > mid)
return ask(mid + 1, pr, tr[x].R, tr[y].R, num);
}
int main()
{
run();
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
bt(1, n);
for (int i = 1; i <= n; i++)
root[i] = update(root[i - 1], 1, 3e5, a[i]);
while (m--)
{
int opt, l, r, x;
cin >> opt;
if (opt == 1)
{
cin >> l >> r >> x;
cout << ask(1, 3e5, root[l - 1], root[r], x) << endl;
}
else
{
cin >> x;
if (a[x] == a[x + 1])continue;
root[x] = change(root[x - 1], 1, 3e5, a[x + 1]);
root[x + 1] = change(root[x], 1, 3e5, a[x]);
swap(a[x], a[x + 1]);
}
}
return 0;
}
100的代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define pii pair<int,int>
#define pll pair<long,long>
#define ls(k) (k*2) //抽象点的
#define rs(k) (k*2+1)
#define all(x) (x).begin(), (x).end()
#define do_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
using namespace std; void run() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); }
#define endl "\n"
// /**/ #define endl "\n\n"
const int N = 1e6 + 10;
int root[N], a[N];
struct SegmentTreeNode
{
int L = 0, R = 0, sum = 0;
}tr[N<<5];
int cnt = 0, n, m;
int bt(int pl, int pr)
{ //pl==pr也是在这里编号了
int rt = ++cnt; //为当前树的编号
tr[rt].sum = 0; //sum是统计数量
if (pl == pr)return rt;
int mid = pl + pr >> 1;
tr[rt].L = bt(pl, mid);
tr[rt].R = bt(mid + 1, pr);
return rt;
}
int update(int p, int pl, int pr, int num, int k)
{
int rt = ++cnt;
tr[rt] = tr[p];
tr[rt].sum = tr[p].sum + k;
if (pl == pr)
return rt;
int mid = (pl + pr) >> 1;
if (num <= mid)
tr[rt].L = update(tr[p].L, pl, mid, num,k);
if(num>mid)
tr[rt].R = update(tr[p].R, mid + 1, pr, num,k);
return rt;
}
int ask(int pl, int pr, int x, int y, int num)
{
if (pl == pr)
return tr[y].sum - tr[x].sum;
int mid = (pl + pr) >> 1;
if (num <= mid)
return ask(pl, mid, tr[x].L, tr[y].L, num);
if(num>mid)
return ask(mid + 1, pr, tr[x].R, tr[y].R, num);
}
int main()
{
run();
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
bt(1, n);
for (int i = 1; i <= n; i++)
root[i] = update(root[i - 1], 1, 3e5, a[i],1);
while (m--)
{
int opt, l, r, x;
cin >> opt;
if (opt == 1)
{
cin >> l >> r >> x;
cout << ask(1, 3e5, root[l - 1], root[r],x) << endl;
}
else
{
cin >> x;
if (a[x] == a[x + 1])continue;
root[x] = update(root[x], 1, 3e5, a[x],-1);
root[x] = update(root[x], 1, 3e5, a[x+1],1);
swap(a[x], a[x + 1]);
}
}
return 0;
}