树上逆序对 思维+树状数组
思维
1,看到逆序对,还是树上和父节点有关系的,就想到树状数组来统计小于等于x的数的个数,只需维护一下该点到根节点的树状数组即可。dfs正好满足。
2,只求一边好求O(n),但是这可能要m次,就不能暴力了,每次处理最多 O(1) 或 O(log(n)) 的复杂度。
3,在线算法不好想,故考虑离线算法,把所有要加入的点先全部加上
4,如果每次询问,不考虑删除以u为根的子树的话,只求此时的逆序对的个数,可以维护一下在此次询问之前的加入的点产生的总贡献即可。
5,对删除u为根的子树来说,只需在dfs到u时,记录一下其子树对该次询问产生的总贡献,然后再用此时总共的逆序对减去子树的贡献即可。
6,注意要离散化
时间复杂的O(nlog(n))
/*
hello world!
Just do it!
start time:2022-05-04 10:23:59.416199
*/
// #pragma GCC optimize (2)
// #pragma G++ optimize (2)
#include <bits/stdc++.h>
#define zero(x) memset(x, 0, sizeof(x));
#define one(x) memset(x, -1, sizeof(x));
#define m_INF(x) memset(x, 0x3f, sizeof(x));
#define m_inf(x) memset(x, 0x3f, sizeof(x));
#define m_f_INF(x) memset(x, -0x3f, sizeof(x));
#define m_f_inf(x) memset(x, -0x3f, sizeof(x));
#define all(x) x.begin(), x.end()
#define endl "\n"
#define fi first
#define se second
#define lbt(x) ((x)&(-x))
#define pb push_back
struct cmpl{ template <typename A, typename B> bool operator()(const A &a1, const B &b1) { return b1 < a1; } };
struct cmpg{ template <typename A, typename B> bool operator()(const A &a1, const B &b1) { return a1 < b1; } };
#define p_ql(x) priority_queue<x, vector<x>, cmpl>
#define p_qlp(x, y) priority_queue<pair<x, y>, vector<pair<x, y>>, cmpl>
#define p_qg(x) priority_queue<x, vector<x>, cmpg>
#define p_qgp(x, y) priority_queue<pair<x, y>, vector<pair<x, y>>, cmpg>
template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
#define fo(i,from,to) for(int i=(from),ooo=(from)<(to)?1:-1,oooo=(to)+ooo;i!=oooo;i+=ooo)
#define fol(i,from,to) for(long long i=(from),ooo=(from)<(to)?1:-1,oooo=(to)+ooo;i!=oooo;i+=ooo)
#define foo(i,ooo) for(auto i=ooo.rbegin();i!=ooo.rend();++i)
#define foa(i,from,to) for(int i=(from),ooo=(to);i<=ooo;++i)
#define fos(i,from,to) for(int i=(from),ooo=(to);i>=ooo;--i)
using namespace std;
#ifndef LOCAL
# define dbg(...) ;
#endif
#define itn int
#define int long long
#ifdef int
#define inf (0x3f3f3f3f3f3f3f3f)
#else
#define inf (0x3f3f3f3f)
#endif
typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii;
const int dir[8][2]={{0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}}, INF = 0x3f3f3f3f, f_inf = -1044266559, f_INF = -1044266559;
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 10;
const int N = 1e6 + 10;
int n, m;
void init()
{
}
int c[N];
void add(int x, int v)
{
for(; x < N; x += lbt(x)) c[x] += v;
}
int ask(int x)
{
int res = 0;
for(; x; x -= lbt(x)) res += c[x];
return res;
}
int c2[N];
void add2(int x, int v)
{
for(; x < N; x += lbt(x)) c2[x] += v;
}
int ask2(int x)
{
int res = 0;
for(; x; x -= lbt(x)) res += c2[x];
return res;
}
vector<int> gr[N];
vector<int> task[N];
int a[N], id[N];
int f[N], ans[N];
void dfs(int r, int fa)
{
for(auto &x : task[r]) {
ans[x] = ask2(x - 1);
}
add2(id[r], ask(N - 1) - ask(a[r]));
add(a[r], 1);
for(auto &x : gr[r]) {
if(r == fa) continue;
dfs(x, r);
}
add(a[r], -1);
for(auto &x : task[r]) {
ans[x] -= ask2(x - 1);
}
}
void solve()
{
cin >> n >> m;
foa(i, 1, n) cin >> a[i];
id[1] = 1;
foa(i, 2, n) {
int fa;
cin >> fa;
gr[fa].pb(i);
id[i] = 1;
}
int nums = n;
vector<int> vt;
foa(i, 1, m) {
int k;
cin >> k;
if(k == 1) {
int u, x;
cin >> u >> x;
++nums;
a[nums] = x;
id[nums] = i + 1;
gr[u].pb(nums);
} else {
int k;
cin >> k;
task[k].pb(i + 1);
vt.pb(i + 1);
}
}
vector<int> v1;
foa(i, 1, nums) v1.pb(a[i]);
sort(all(v1));
v1.erase(unique(all(v1)), v1.end());
foa(i, 1, nums) a[i] = lower_bound(all(v1), a[i]) - v1.begin() + 1;
dfs(1, 0);
for(auto &x : vt) {
int res = ask2(x) + ans[x];
cout << res << endl;
}
}
signed main()
{
#ifdef LOCAL
freopen("read.in", "r", stdin);
freopen("write.out", "w", stdout);
#endif
std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0);
init();
int t = 0, num2 = 0;
t = 1;
if (!t) cin >> t;
while (t--) {
//cout<<"Case "<<++num2<<": ";
solve();
}
return 0;
int num1 = 0;
//while (scanf("%d", &n) !=-1 && n)
while (cin >> n && n) {
//cout<<"Case "<<++num1<<": ";
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」