効果:無向グラフが与えられると、点I $ $ $ B_i $右点、エッジ$(x、y、z)を$配列$ A [b_x \ oplus b_y] $プラス$ Zは$の寄与です。
セット質問複数の、3つの動作の合計:1.右端ポイント2変形例3権要求シーケンスと$ A $の間隔を変更します。
ブロックすることにより、図度。
直接寄与フェンウィックツリーメンテナンス複雑さの$ Oのタップ(17 \ SQRT {M})$
各重側は$ [L、の範囲内で[X] $ $ [L、R] $間隔を求め、組み込みの$ Xの$する$ 01trie $の焦点のより大きな程度から選択され、発散または$ Bと同等ですR&LT] $と複雑さの$ O(17 \ SQRT {M})$。
書式#include <iostreamの> の#include <sstream提供> する#include <アルゴリズム> 書式#include <cstdioを> する#include <math.h>の 書式#include <設定> 書式#include <マップ> 書式#include <キュー> の#include <string>に する#include < string.hの> の#include <ビットセット> の#define REP(I、N)のために(INT iは=; I <= N; ++ I) の#define PER(I、N)のための(iはint型= N; I> = A; - I) の#defineのHRのputchar(10) の#define PB一back の#define LC(O << 1) の#define RC(LC | 1) の#define中間((L + R)>> 1) の#define LS LC、L、中 の#define RSのRC、ミッド+ 1、R用 の#defineは、最初のx の#define yの第二 のstd :: IOS IOの#defineを::sync_with_stdio(偽) の#define ENDL '\ n'は #define DB(A)({REP(__ I、1、n)はCOUT << [__ I] <<」「;}時間) 名前空間stdを使用。 typedefの長い長いLL。 typedefのペア<int型、int型> PII。 const int型P = 998244353; const int型N = 131080; const int型S = 4000; INTのN、M、Q、X [N]、Y [N]、Z [N]。 INT B [N]、度[N]、ID [N]、E [N]。 ベクトル<整数>大、小[N]; 構造体{ LLのC [N]。 ボイド追加(int型のx、int型V){ ため(++ X; X <Nであり、X + = X&-x)C [X] + = V。 } LL QRY(INT X){ LLのRET = 0。 用(++ X; X; X ^ = X&-x)RET + = C [X]。 RETを返します。 } } BIT。 構造体{ INT T、TOT。 構造体{INT CH [2]、V;} [N << 2]。 無効アドオン(INT&O、int型のD、int型のx、int型V){ O = ++ TOTの場合(O!)。 [O] .V =([O] .V + V)%のP。 (D> = 0)([X >> D&1]、D-1、X、V .CH [O])を追加した場合。 } ボイド追加(int型のx、int型V){ (V、T、16、X)を加えます。 } のLL QRY(int型D、Oのint、int型のx、int型V){ (D <0)[O] .Vを返す場合、 int型F1 = X >> D&1、F2 = V >> D&1; (F2)を返す場合は[O] .CH [F1] V + QRY([O] .CH、D-1、X、V [F1!])。 QRY返す([O] .CH [F1]、D-1、X、V)。 } LL QRY(int型のx、int型V){ LL RET = QRY(T、16、X、V)。 RETを返します。 } } TR [100]。 ボイド追加(INT IDを、int型のTP){ IF(E [ID])TR [E [ID]。追加(B [X [ID]] ^ B [Y [ID]] ^ B [ビッグ[E [ID ]]]、TP * Z [ID])。 他BIT.add(B [X [ID]] ^ B [Y [ID]、TP * Z [ID])。 } INT QRY(INT X){ IF(X <0)戻り0; LL ANS = BIT.qry(X)。 (I 1 = int型、iが(big.sizeを<); ++ i)について{ ANS + = TR [I] .QRY(B [ビッグ[i]が]、X)。 } ANS%のPを返します。 } int型のmain(){ scanf関数( "%D%D%D"、&N、&M&Q)。 REP(I、1、N)のscanf( "%dの"、B + I)。 REP(I、1、M){ scanf関数( "%D%D%D"、X + I、Y + I、Z I +)。 ++度[X [I]、++度[Y [I]]。 } big.pb(0)。 REP(I、1、N)の場合(DEG [I]> = S){ ID [I] = ++ * ID。 big.pb(I); } REP(I、1、M){ IF(ID [X [I]] &&度[X [I]]> DEG [Y [I]]){ E [I] = ID [X [I]]。 小[Y [I] PB(I)。 E [I] = ID [Y [I]]。 小さな[X [I] PB(I)。 他{ 小さな[X [I] PB(I)。 小[Y [I] PB(I)。 } 追加(I、1)。 } 一方(q--){ int型のOP、X、Y。 scanf関数( "%D%D%D"、&OP、およびX&Y)。 (OP == 1)は{場合 (自動T:小さな[X])のための追加(T、-1)。 B [X] Yを=。 (自動T:小さな[X])のための追加(T、1); } もしそうでなければ(OP == 2){ (X -1)を加えます。 Z [X] Yを=。 追加(X、1)。 } 他{ int型ANS =(QRY(Y)-qry(X-1))%のP。 (ANS <0)ANS + = Pなら printf( "%d個の\ n"、ANS)。 } } }