私はまた、いくつかの水問題を行います
式見つけやすい、分離I、のみ回答のL、R及びVを発見する[I]、V [i]は* I、V間隔[I] * iはiと関連します*
メンテナンスは、3つのセグメントツリーを使用することができます
書式#include <iostreamの> の#include <cstdioを> に#define llint長いlong int型 使用して 名前空間はstdを、 const int型 MAXN = 400005 ; 構造体atree1 { llintのTN、LS [MAXN]、RS [MAXN]和[MAXN]、JS [MAXN]、怠惰[MAXN]、FA [MAXN]。 ボイドCLE(){ TN = 1 。 } ボイドビルド(llintのX、llintのLL、llintのRR、llintのF){ 場合(LLの==のRR){ 和[X] = 0 ; もし(== F 1 JS [LL] =のJS)LL- 1 ] +LL; そう であれば(== F 2 [LL] = JSのJS)LL- 1 ] + LLの*のLL。 そう であれば(Fの== 3)JS [LL] = LL。 } 他{ llint半ば =(LL + RR)/ 2 。 TN ++; LS [X] = TN。FA [TN] =のX。(TN、LL、ミッド、F)を構築します。 TN ++; RS [X] = TN。FA [TN] = xと; 構築(TN、ミッド+ 1 、RR、F)。 和[X] =和[LS [X] + 和[RS [X]]。 } を返します。 } のボイド(llintリットル、llintのR、llintのNUM、llintのX、llintのLL、llintのRR)を追加{ 場合(L> RR || LL> R)リターン; もし(L <= 11 && RR <= r)は怠惰[X] + = NUM。// COUT << ' '<< LL <<'' << RR << ENDL、 他{ llint半ば =(LL + RR)/ 2 。 和[X] + =(JS [分(R、RR)] - JS [MAX(L、LL) - 1 ])* NUM。 // COUT << ' '<< LL <<' '<< RR <<'' <<和[X] << ENDL。 追加(L、R、NUM、LS [x]は、LL、MID)。 追加(L、R、NUM、RS [x]は、中間 + 1 、 RR); } を返します。 } llintカウント(llintリットル、llintのR、llintのX、llintのLL、llintのRR){ 場合(L> RR || LL> R)戻り 0 。 もし(L <= 11 && RR <= r)は戻り和[X] +(JS [RR] -js [LL- 1 ])* 怠惰[X]。 他{ llint半ば =(LL + RR)/ 2 。 和[X] + =(JS [RR] -js [LL- 1 ])* 怠惰[X]。 怠惰[LS [X] + =怠惰[X]。怠惰[RS [X] + =怠惰[X]。怠惰[X] = 0 。 戻り数(L、R、LS [x]は、LL、MID)+カウント(L、R、RS [x]は、中間+ 1 、RR)。 } } } T1、T2、T3。 llintのGCD(llintのB、llint){ 場合(Bの== 0)を返します。 戻り GCD(B、%のB)。 } int型のmain(){ IOS :: sync_with_stdio(偽)。 llint I、N、M、L、R、TA、ANS1、ANS2。 char型トンを。 CIN >> N >> M。 T1.cle(); T2.cle(); T3.cle(); T1.build(1、1、nは、1 )。 T2.build(1、1、nは、2 ); T3.build(1、1、N、3 ); 用(i = 1 ; I <= M; iは++ ){ CIN >> T。 もし(T == ' C ' ){ CIN >> L >> R >> TA。 R - ; T1.add(L、R、TA、1、1 、N) T2.add(L、R、TA、1、1 、N) T3.add(L、R、TA、1、1 、N) } 他{ CIN >> L >> R。 ANS1 = T1.count(L、R、1、1、N)*(R + 1- 1)-T2.count(L、R、1、1、N) - (のL * RR)* T3.count( L、R、1、1 、N) ANS2 =(RL + 1)*(RL)/ 2 。 TA = GCD(ANS1、ANS2)。 coutの << ANS1 / TA << ' / ' << ANS2 / TA << てendl; } } 戻り 0 。 }