フェンウィックツリー+オイラー降順



タイトル説明

配列の長さ、操作のM nは、各操作:
1.区間 [L、R&LT] [Lは、R] 、[ L R&LT ]プラスXX X
間隔2. [L、R&LT] [Lは、R] 、[ L R&LT ]、クエリ[L] [L + 1] [L + 2] ... [L] ^ {A [L + 1] A ^ {[L + 2]}} ... A [ L ]は、A [ L + 1 ] A [ L + 2 ] modmodのM OのDの  PPのP、までAAのA-のRRのR
異なる弾性係数の各のでご注意ください。

説明を入力します。

nは二つの整数の最初の行、mは配列の長さおよび操作の数を表し、

N-整数、次の行は、一連のことを示す

:次の行のMは、次の2つの操作のいずれかであってもよい

動作1:区間[L、R]プラスXの

動作2:クエリ値区間[L、R]、式のMOD P

出力説明:

各お問い合わせは、数の出力は、答えを示し、
例1

エントリー

コピー
6 4 
1 2 3 4 5 6 
2 1 2 10000007 
2 2 3 5 
1 1 4 1 
2 2 4 10

輸出

コピー
1 
3 
1

備考:

N、M <= 500000 

各[1,2e9]以内、X <= 2E9、P <におけるシーケンス番号 = 2E7

<ビット/ STDC ++ H>の#include 
の#include <TR1 / unordered_map> 
のtypedef長い長LL。
名前空間stdを使用。
const int型MAXN = 2E7 + 9。
CONSTのINT MAX = 1E5 + 9。
BOOL VIS [MAXN]。
int型のCNT、プリム[MAXN]、PHI [MAXN]、N。
LL [MAXN]。
typedefのペア<LL、int型> P; 

インラインINT lowbit(INT X)
{ 
	戻りX&( - X)。
} 

インラインボイド更新(int型L、int型K)
{ 
	(L <= n)の一方
	{ 
		[L] + = K。
		L + = lowbit(L)。
	} 
} 

インラインLLクエリ(INT 1)
{ 
	LL ANS = 0。
	(L)、一方
	{ 
		ANS + = [L]。
		1- = lowbit(L)。
	} 
	戻りANS。
}

インライン読み取り()っ
{ 
	LL RES = 0。
	チャーC = GETCHAR()。
	(!isdigit(c)参照)ながら、C = getchar関数(); 
	一方、(isdigit(c)参照)のRES =(RES << 1)+(RES << 3)+ C-48、C = GETCHAR()。
	解像度を返します。
} 

インラインボイドのinit()
{ 
	LL I、J。
	VIS [1] = PHI [1] = 1。
	以下のための(I = 2; I <= MAXN-9; iは++)
	{ 
		IF(VIS [I]!)
		{ 
			プリム[++ CNT] = I。
			PHI [i]は= I-1。
		} 
		ため(J = 1; J <= iがプリム[j]を* && CNT <= MAXN-9; ++ j)は
		{ 
			VIS [i *がプリム[J] = 1。
			IF(I%プリム[j] == 0)
			{ 
				PHI = PHI [I] *プリム[J] [iがプリム[J] *]を、破ります; 
			} 
			PHI [iが*プリム[J] = PHI [I] *(プリム[J] -1)。
		} 
	} 
}

Pパウ(-1,11,11-のB、LLのP)
{ 
	LL ANS = 1、TEMP = 1、I。
	INTフラグ= 0。
	用(i = 1; iは= bを<; iは++)
	{ 
		TEMP = TEMP *。
		IF(TEMP> = P)
		{ 
			フラグ= 1;破ります。
		} 
	} 
	%= P。
	(b)は、一方
	{ 
		IF(B&1)ANS = ANS *%のP。
		= A *%pを。
		B >> = 1。
	} 
	P(ANS、フラグ)を返します。
} 

インラインPのgetans(LLのL、R -1,11,11-のP)
{ 
	=クエリ(L)LL。
	IF(== 1 || L == R || P == 1)リターンP(%のP、A> = P 1:0)。
	P bの= getans(L + 1、R、PHI [P])。
	IF(b.second)b.first + = PHI [P]。
	パウ(b.first、p)を返します。
} 

int型のmain()
{ 
	int型M、I。
	scanf関数( "%d個の%のD"、&N、&M)。
	初期化(); 
	用(i = 1; iが<= N; iは++)
	{ 
		LL。
		scanf関数( "%のLLD"、&A); 
		アップデート(I、A)。
		アップデート(I + 1、-a)。
	} 
	(M--)一方
	{ 
		INT OPT。
		LLのL、R、X。
		scanf関数( "%D%LLD%LLD%LLD"、&オプト、&​​L&R&X)。
		IF(OPT == 1)
		{ 
			更新(L、X)。
			更新(R + 1、-X)。
		} 
		{ 
			のprintf( "%LLDする\ n"、getans(L、R、X)1次回)。
		} 
	} 
}

リンク:https://ac.nowcoder.com/acm/problem/17190
出典:牛オフネットワーク

おすすめ

転載: www.cnblogs.com/HHHEN/p/11782694.html