Please help me optimize my code
#pragma GCC optimize(“Ofast”)
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-finline")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-fno-stack-protector")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-funroll-loops")
#pragma GCC target(“abm”)
#pragma GCC target(“avx”)
#pragma GCC target(“mmx”)
#pragma GCC target(“popcnt”)
#pragma GCC target(“sse”)
#pragma GCC target(“sse2”)
#pragma GCC target(“sse3”)
#pragma GCC target(“sse4”)
#pragma GCC target(“ssse3”)
#pragma GCC target(“tune=native”)
#include <bits/stdc++.h>
using namespace std;
struct Node{
Node *l,*r;int sum;
Node(int val):l(nullptr),r(nullptr),sum(val){}
Node(Node *l,Node *r):l(l),r®,sum(0){
if (l!=nullptr) sum+=l->sum;
if (r!=nullptr) sum+=r->sum;
}
Node(Node *cp):l(cp->l),r(cp->r),sum(cp->sum){}
};
#define MAXN 100001
#define MAXM 17
int n,m,timer=1;
int a[MAXN];
vector kompresija,adj[MAXN],pos[MAXN];
int dist[MAXN],parent[MAXM][MAXN],tin[MAXN],tout[MAXN];
Node* root[MAXN];
void dfs(int node,int pret,int depth)
{
tin[node]=timer;timer++;
dist[node]=depth;parent[0][node]=pret;
for (int sled:adj[node])
{
if (sled==pret) continue;
else dfs(sled,node,depth+1);
}
tout[node]=timer-1;
}
Node* build(int l,int r)
{
if (l==r) return new Node(0);
int mid=(l+r)/2;return new Node(build(l,mid),build(mid+1,r));
}
Node* update(Node* node,int l,int r,int pos,int val)
{
if (l==r) return new Node(node->sum+val);
int mid=(l+r)/2;
if (pos<=mid) return new Node(update(node->l,l,mid,pos,val),node->r);
else return new Node(node->l,update(node->r,mid+1,r,pos,val));
}
int query(Node* node,int l,int r,int aa,int bb)
{
if (aa>bb) return 0;
if (l==aa and r==bb) return node->sum;
int mid=(l+r)/2;
return query(node->l,l,mid,aa,min(bb,mid))+query(node->r,mid+1,r,max(aa,mid+1),bb);
}
int jump(int node,int k)
{
int stepen=0;
while (k>0)
{
if (!(k&(1<<stepen))) {stepen++;continue;}
node=parent[stepen][node];k-=(1<<stepen);stepen++;
}
return node;
}
int lca(int node1,int node2)
{
if (dist[node1]<dist[node2]) swap(node1,node2);
node1=jump(node1,dist[node1]-dist[node2]);
if (node1==node2) return node1;
for (int i=MAXM-1;i>=0;i–)
{
if (parent[i][node1]!=parent[i][node2]) {node1=parent[i][node1];node2=parent[i][node2];}
}
return parent[0][node1];
}
int main()
{
ios_base::sync_with_stdio(false);
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);cin>>n>>m;
for (int i=1;i<=n;i++) {cin>>a[i];kompresija.push_back(a[i]);}
sort(kompresija.begin(),kompresija.end());kompresija.erase(unique(kompresija.begin(),kompresija.end()),kompresija.end());
for (int i=1;i<=n;i++) {a[i]=lower_bound(kompresija.begin(),kompresija.end(),a[i])-kompresija.begin();pos[a[i]].push_back(i);}
for (int i=1;i<n;i++) {int x,y;cin>>x>>y;adj[x].push_back(y);adj[y].push_back(x);}
dfs(1,0,0);
for (int i=1;i<MAXM;i++)
{
for (int node=1;node<=n;node++) parent[i][node]=parent[i-1][parent[i-1][node]];
}
root[0]=build(1,n);
for (int node:pos[0])
{
root[0]=update(root[0],1,n,tin[node],1);
if (tout[node]!=n) root[0]=update(root[0],1,n,tout[node]+1,-1);
}
for (int i=1;i<kompresija.size();i++)
{
root[i]=new Node(root[i-1]);
for (int node:pos[i])
{
root[i]=update(root[i],1,n,tin[node],1);
if (tout[node]!=n) root[i]=update(root[i],1,n,tout[node]+1,-1);
}
}
for (int i=1;i<=m;i++)
{
int node1,node2,k;cin>>node1>>node2>>k;int c=lca(node1,node2);
int l=0,r=kompresija.size()-1,rez=kompresija.size()-1;
while (l<=r)
{
int mid=(l+r)/2;
int ans=query(root[mid],1,n,1,tin[node1])+query(root[mid],1,n,1,tin[node2])-2*query(root[mid],1,n,1,tin[c])+query(root[mid],1,n,tin[c],tin[c]);
if (ans>=k) {rez=mid;r=mid-1;}
else l=mid+1;
}
cout<<kompresija[rez]<<endl;
}
}