#include #include #include #include using namespace std; const int MAXN = 1e5 + 5; struct LinkedList { int x; LinkedList *nxt, *last; LinkedList(){} LinkedList(int x) { this->x = x; this->last = this; this->nxt = nullptr; } LinkedList(const LinkedList& other) { this->x = other.x; this->nxt = other.nxt; this->last = other.last; } void mergeList(LinkedList *other) { last->nxt = other; last = other->last; } }; struct DSU1 { int parent[MAXN]; LinkedList *l[MAXN]; DSU1(){} DSU1(int n) { for(int x = 1;x<=n;x++) { parent[x] = x; l[x] = new LinkedList(x); } } int Find(int x) { if(parent[x]==x) return x; parent[x] = Find(parent[x]); return parent[x]; } void Union(int u, int v) { u = Find(u); v = Find(v); parent[v] = u; l[u]->mergeList(l[v]); } }; int n, Q; int64_t a[MAXN]; vector , int>> edges; vector nodeOrder; int node2OrderPos[MAXN]; struct DSU2 { int parent[MAXN]; int lInd[MAXN], rInd[MAXN]; DSU2(){} DSU2(int n) { for(int x = 1;x<=n;x++) { parent[x] = x; lInd[x] = rInd[x] = node2OrderPos[x]; } } int Find(int x) { if(parent[x]==x) return x; parent[x] = Find(parent[x]); return parent[x]; } void Union(int u, int v) { u = Find(u); v = Find(v); parent[v] = u; lInd[u] = min(lInd[u], lInd[v]); rInd[u] = max(rInd[u], rInd[v]); } }; void constructOrder() { DSU1 *dsu = new DSU1(n); for(auto e: edges) dsu->Union(e.first.first, e.first.second); int root = dsu->Find(1); LinkedList *x = dsu->l[root]; while(x!=nullptr) { nodeOrder.push_back(x->x); node2OrderPos[x->x] = nodeOrder.size() - 1; x = x->nxt; } delete dsu; } struct QuestionData { int l, r; QuestionData(){} QuestionData(int l, int r) { this->l = l; this->r = r; } }; struct Query { int ind; int t; int64_t x, l; Query(){} Query(int ind, int t, int x, int l) { this->ind = ind; this->t = t; this->x = x; this->l = l; } QuestionData data; }; vector questions, updates, allQueries; void evalQuestionData() { sort(questions.begin(), questions.end(), [](const Query& A, const Query& B) { if(A.l!=B.l) return A.lFind(questions[qPtr].x); questions[qPtr].data = QuestionData(dsu->lInd[root], dsu->rInd[root]); qPtr++; } dsu->Union(e.first.first, e.first.second); } while(qPtrFind(questions[qPtr].x); questions[qPtr].data = QuestionData(dsu->lInd[root], dsu->rInd[root]); qPtr++; } delete dsu; } struct SegmentTree { int64_t sum; int l, r; SegmentTree *L, *R; SegmentTree() : sum(0), L(nullptr), R(nullptr) {} SegmentTree(int l, int r) : SegmentTree() { this->l = l; this->r = r; } void recalc() { sum = L->sum + R->sum; } void build(int64_t *a) { if(l==r) { sum = a[l+1]; return; } L = new SegmentTree(l, (l+r)/2); R = new SegmentTree((l+r)/2+1, r); L->build(a); R->build(a); recalc(); } void update(int q, int64_t newVal) { if(l==r && l==q) { sum = newVal; return; } if(rq) return; L->update(q, newVal); R->update(q, newVal); recalc(); } int64_t query(int ql, int qr) { if(ql>qr) return 0; if(l>=ql && r<=qr) return sum; if(rqr) return 0; return L->query(ql, qr) + R->query(ql, qr); } }; int main() { ifstream cin("thief.in"); ofstream cout("thief.out"); ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> Q; for(int x = 1;x<=n;x++) cin >> a[x]; for(int i = 0;i> u >> v >> val; edges.push_back({make_pair(u, v), val}); } sort(edges.begin(), edges.end(), [](pair , int> A, pair , int> B) { if(A.second!=B.second) return A.second> t >> x >> l; Query query(q, t, x, l); if(t==1) questions.push_back(query); else updates.push_back(query); } evalQuestionData(); int uPtr = 0; sort(questions.begin(), questions.end(), [](const Query& A, const Query& B) { return A.indbuild(a); for(const Query& q: questions) { while(uPtrupdate(node2OrderPos[updates[uPtr].x], updates[uPtr].l); uPtr++; } cout << T->query(q.data.l, q.data.r) << '\n'; } }