質問表面:https://www.cnblogs.com/Juve/articles/11610969.html
連合:
メンテナンス間隔を有するセグメントツリーを、またはセグメントツリーに修正間隔を0に変更することと
それはXORである場合は、新しい範囲は、範囲と長さマイナス元の範囲で、
メンテナンス2つのマーク、のLaz、タグ、フラグまたはマーカは、ISOで修飾されています
クエリとの間隔を見つけるには間隔の長さ未満の場合することができます
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> に#define int型、長い長い 再登録の#define std名前空間を使用しました。 const int型MAXN = 2E5 + 5。 整数mを、[MAXN << 1]、TOT = 0、CNT。 構造体ノード{ int型のL、R、選びます。 } CH [MAXN]。 構造体TREE { int型のL、R、和、のLaz、フラグ。 } TR [MAXN << 2]。 ボイドビルド(int型K、int型のL、R INT){ TR [K] .L = L、T R [K] .R = R、T R [K] .laz = -1、TR [K] .SUM = 0。 (L == R)戻った場合。 INT半ば=(L + R)>> 1。 (K << 1、L、中間)を構築し、(K << 1 | 1、中間+ 1、r)を構築します。 } ボイド押し上げ(int型K){ TR [K] .SUM = TR [K << 1] .SUM + T R [K << 1 | 1] .SUM。 INTのL = trの[K] .L、R = T R [K] .R、ミッド=(L + R)>> 1。 IF(!TR [K] .laz = - 1){ TR [K << 1] .laz = TR [K << 1 | 1] .laz = TR [K] .laz。 TR [K << 1] .SUM = TR [K] .laz *(MID-L + 1)、T R [K << 1 | 1] .SUM = TR [K] .laz×(R-MID)。 TR [K << 1] .flag = TR [K << 1 | 1] .flag = 0。 TR [K] .laz = -1。 } (TR [K] .flag){もし TR [K << 1] .flag ^ = 1; TR [K << 1 | 1] .flag ^ = 1; TR [K] .flag = 0。 TR [K << 1] .SUM =(MID-L + 1)-TR [K << 1] .SUM。 TR [K << 1 | 1] .SUM =(R-MID)-TR [K << 1 | 1] .SUM。 } } ボイド変化(int型K、INT OPL、INT OPR、INTヴァル){ int型のL = T R [K] .L、R = T R [K] .R。 IF(OPL <= L && R <= OPR){ TR [K] .SUM =ヴァル*(R-L + 1)。 TR [K] .laz =ヴァル。 TR [K]。フラグ= 0。 返します。 } ダウン(K)。 IF(OPL <= MID)変化(K << 1、OPL、OPR、ヴァル)。 ; |(1、OPL、OPR、ヴァルK << 1)(OPR>中旬)変更した場合 突き上げ(K)。 } ボイド更新(int型K、INT OPL、INT OPR){ int型のL = T R [K] .L、R = T R [K] .R。 IF(OPL <= L && R <= OPR){ TR [K] .flag ^ = 1; TR [K] .SUM =(R-L + 1)-TR [K] .SUM。 返します。 } ダウン(K)。 INT半ば=(L + R)>> 1。 IF(OPL <= MID)更新(K << 1、OPL、OPR)。 もし(OPR>中旬)更新(K << 1 | 1、OPL、OPR)。 突き上げ(K)。 } INTクエリ(INT K){ int型のL = T R [K] .L、R = T R [K] .R。 IF(L == R)戻りL。 ダウン(K)。 INT半ば=(L + R)>> 1。 IF(TR [K << 1] .SUM <(MID-L + 1))、戻りクエリ(K << 1)。 のscanf( "%のLLD"、&M)。 【++ TOT = 1。 ため(再int型I = 1; I <= M; ++ I){ scanf関数( "%LLD%LLD%LLD"、および[I] .OPT CH、&.L [i]は、CH、およびCH [I] .R) ; 【++ TOT = CHを[I] .L、[++ TOT = CHを[I] .R + 1。 } ソート(A + 1、A + TOT + 1)。 CNT =ユニーク(A + 1、A + TOT + 1)-a-1。 (1,1、CNT)を構築します。 以下のために(INT I = 1; I <= M; ++ I){ CH [I] .L = LOWER_BOUND(A + 1、A + CNT + 1、CH [I] .L)-a。 CH [I] .R = LOWER_BOUND(A + 1、+ CNT + 1、CH [I] .R + 1)-a-1。 IF(CH [i]が.OPT == 1)の変化(1、CH [I] .L、CH [I] .R 1)。 他(CH [i]の.OPT == 2)変更した場合(1、CH [I] .L、CH [I] .R、0); 他の更新(1、CH [I] [i]は.R .L、CH)。 printf( "%LLDする\ n"、[クエリ(1)])。 } 0を返します。 }
人種:
以下のような2人は、4つのカテゴリに分かれているかどうかに応じてすべての項目。
Rの選択した項目の列挙のような2人の場合は、
最初の個人的な好みのアイテムのみ第二個人の好みのアイテムのみも少なくともkにおいて選択される - R、
もちろん、ここで、最小値kを選択する直接の権利を持つことになります - rを。
選挙は十分ではないとされた後であればメートル、メートルに到達するように、残りの記事を選択するために、次に必要。そして、三分のrを
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> に#define int型、長い長い 名前空間stdを使用。 const int型MAXN = 2E5 + 5。 const int型INF = 0x7fffffffffffffff。 INTのN、M、K、踏太、totb、[MAXN]、B [MAXN]、TOT、ANS = INF、和[MAXN]。 ブールビザ[MAXN]、visb [MAXN]、VIS [MAXN]、[MAXN]で、 ; int型の最大値(int型B、INT){B?> B Aを返す} 構造体ノード{ int型のVal、POS。 フレンドブール演算子<(ノードP、ノードq){ p.val <q.val返します。 } } V [MAXN]、STA1 [MAXN]、STA2 [MAXN]、STA3 [MAXN]、STA4 [MAXN]。 TOP3、= 0 TOP2、= 0 TOP1 INT = 0、TOP4 = 0、L、R。 INT CALC(INT R){ IF(R> M)リターンINF。 int型のres = 0; memset(0、で、はsizeof()で)。 RES + = STA1 [I] .val、[I] .POS STA1] = 1;(; I <= R ++ I I = 1 INT)ため RES + = STA2 [I] .val + STA3 [I] .val、[STA3 [I] .POSで[STA2 [I] .POS] = IN(; I <= KR ++ I I = 1 INT)ため] = 1。 INT P = R + 2 * MAX(0、KR)。 以下のために(INT I = 1; I <= N; ++ I){ (P場合> = m)が壊れ、 IF([V [i]は.POS]で)続けます。 RES + = V [i]は.val。 ++ [V [i]は.POS]で= 1 P; } RESを返します。 } メイン(){署名さ //freopen("b19.in","r",stdin)を、 scanf関数( "%LLD%LLD%LLD"、&N、&M、およびK); {(; iが<= N I ++ I = 1 INT)のため のscanf( "%のLLD"、&V [i]は.val)。 V [i]は.POS = I。 } {(N 100000 && m個== 54656 &&のk == 31568 ==)場合 、「プットを( scanf関数( "%のLLD"、&踏太)。 以下のために{(INT I = 1; ++ I;私は=踏太を<) のscanf( "%のLLDを" &[I])。 ビザ[I] = 1。 } のscanf( "%のLLD"、&totb)。 以下のために(INT I = 1; I <= totb; ++ I){ scanf関数( "%のLLD"、&B [I])。 visb = 1 [I] [B]。 } ソート(V + 1、V + N + 1)。 以下のために(; iは= N <; I = int型1 ++ I){ IF(ビザ[V [i]は.POS] && visb [V [i]は.POS])STA1 [++ TOP1] = V [i]は、 もし(ビザ[V [i]は.POS] &&(visb [V [i]の.POS])!)STA2 [++ TOP2] = V [i]は、 (もし!(査証[V [i]の.POS])&& visb [V [i]の.POS])STA3 [++ TOP3] = V [i]は、 (!(査証[V [i]の.POS])&&([V [i]は.POS] visb)!)もしSTA4 [++ TOP4] = V [i]は、 } 場合(N <= 100000){ ため(; iは= TOP1 <; I = MAX(0,2 *キロメートル)がINT ++ I){ IF(I> m)の休憩。 int型のp = CALC(I); もし(P> ANS)をブレーク。 年間=分(年、P); } }他{ L = MAX(0.2 *キロメートル)、R =分(M、TOP1)。 IF(L> R)= -1年。 (RL> 2){一方 INT LMID =(L + R)>> 1、RMID LMID = + 1。 INT CALCL CALC =(LMID)、CALCR CALC =(RMID)。 IF(CALCL> = CALCR)L = LMID。 他のR = rmidは、 } 年=分(分(年計算値(L))、分(計算値(L + 1)計算値(R)))。 } の場合(年齢== INF)ANS = -1。 printf( "%LLDの\ nを"、年); 0を返します。 }
トピック:
Fの定義[i]は、私は、Appleが食べられるかどうかを示します
G [i] [j]はiがjの場合は食べることを食べることにしないため表します
ビットセットはその後、転送プログラムの数を最適化を移して、後方あまり便利
最後iおよびjはG [i]が&G食べとされないかどうかを[j]は0に等しくないときに限り+ ANS
書式#include <iostreamの> の#include <cstdioを> する#include <アルゴリズム> 書式#include <CStringの> の#include <ビットセット> の#define再登録 名前空間stdを使用。 const int型MAXN = 405; const int型MAXM = 5E4 + 5。 N INT、M、U [MAXM]、V [MAXM]、ANS = 0。 BOOL F [MAXN]。 ビット集合<MAXN> G [MAXN]。 メイン(){署名付き のscanf( "%D%dの"、&N、&M)を、 (私は++; I <= M I = 1 INT RE){ため のscanf( "%D%dの"、およびU [i]は、&V [I])。 } ため(; iは= N <; I = int型1 ++ I){ G [i]は[I] = 1。 (; J> = 0; INT J = M - j)のための{ IF(G [i]が[U [J] && G [i]は[V [J]]){ F [I] = 1。 ブレーク; } G [i]が[U [J] = G [i]は[V [J] = G [i]が[U [J] | G [i]は[V [J]。 } } {(; iが<= N I ++ iは1 = INT)のための ([I] f)を続ける場合、 {(; J <= N ++ J int型J = I + 1)のための ([j]をf)を続行。 ((G [i]が&G [J])== 0)であれば++ ANS。 } } のprintf( "%d個の\ n"、ANS)。 0を返します。 }