リンク:https://ac.nowcoder.com/acm/contest/82/B
出典:牛オフネットワーク
のスペースの制約:C / C ++ 262144K、他の言語の524288Kの
64ビットIOフォーマット:%LLD
タイトル説明
あなたは長さn、A及び定数kのシーケンスを与えるために、
m回クエリ、区間内の各クエリ[L、R]は、すべてのデータは、連続するセグメントの最小数、および<= kのそれぞれのセグメントに存在します
クエリなしソリューション、出力「Chtholly」の場合
説明を入力します。
最初の3つの数字N、M、Kの列
2行目の数およびn配列を表す
m行の後に、各行は二つの数字LR特定のクエリを表します
出力説明:
M本の出力線、各回答を表す整数
備考:
データの100%に,. 1 <= N、M <= 1000000 ,. 1 <= I、K <= 1000000000
質問の意味:
あなたの配列、および整数k、q倍を与えると、あなたはリットルを頼むたびに尋ね、rに
あなたは、各連続合計がkに等しい未満になるように配列の最小数は、連続した部分に分割されて尋ねます。
アイデア:
二つの229倍の思考、
<20 << 1 1048576あるため= 1E6のでのみ、アレイ乗算器20を開くために必要> 1E6 N以来
我々は、ST [i] [j]が最も遠い1 << jへ、右からi番目の数を表し、アレイ乗算器を開きます
だから我々は我々だけ貪欲を解決する必要があり、各照会のために、この情報を保護します。
LG [i]がLOG2(I)の代表的なRがLから証明することができ、我々は、(1)LOG2のいくつかの番号を選択するために適用されることができる(RL + 1)、LOG2(RL)、LOG2(RL-1)... LOG2到着時に。
だから我々は唯一のより少ないが、その後、より細かい(小さい)一歩を移動した場合R、移動された場合、現在のPOS貪欲右LOG2(R-L + 1)がはるかに少ないようにする必要があります。ことができ、最終的にはRに移動を出力することができるかを決定するかどうかが決定されます。
詳細コードを参照してください。
#include <iostreamの> する#include <cstdioを> する#include <CStringの> する#include <アルゴリズム> の#include <cmath> の#include <キュー> の#include <スタック> の#include <地図> の#include < セット > の#include <ベクトル> #include <iomanip> の#define ALL(X)(X).begin()、(X).END() の#defineを返すRT の#define DLL(X)のscanf( "%I64d"、およびX) の#define XLLを(X )のprintf( "%I64dの\ n"、X) の#define SZ(A)INT(。 サイズ()) の#defineすべて(A)a.begin()、a.end() の#define担当者(I、X、n)のための式(I = xをint型、iがN <; Iは++) の#define(; iが<= N; I = xをint型私は++)のためrepd(I、X、N) の#define PII対< int型、int型> の#define PLLペア<長い長い、長い長い> に#define gbtbイオス:: sync_with_stdio(偽)、cin.tie(0)、cout.tie(0) の#define MS0(X)のmemset((X) 、0、はsizeof((X))) の#define MSC0(X)のmemset((X)、 '\ 0'はsizeof((X))) の#define PB一back の#define融点make_pair の#define Fiの第一 の#define SE第二 #define EPS 1E-6 の#define GG(X)のgetInt(&X) の#define DB(X)COUT << "== [ "<< X <<"] ==" << ENDL。 使用して 名前空間をSTD; typedefの長い 長いLL。 LLのGCD(-1,11,11- b)は{ 戻り B?GCD(B、%のB);} (LLのB LL)LLのLCM { 返す / GCD(A、B)* B;} (MOD -1,11,11-のB LL)LLのpowmod {LL ANS = 1 ; 一方、(b)は、{ もし、(B%2)ANS = ANS *%MOD。= A *%MOD。B / A = 2 ;} 戻りANS;} インラインボイドのgetInt(int型 *のP)。 const int型 MAXN = 1000010 ; const int型 INF =0x3f3f3f3f ; / * **テンプレートコード* **ここから* / LL N、M、K。 LL [MAXN]。 【MAXN] LG LL。 int型 ST [MAXN] [ 21 ]。 INT メイン() { // freopenは( "D:\\ common_text \\ code_stream \\ in.txt"、 "R"、STDIN)。 // freopenは( "D:\\ common_text \\ code_stream \\ out.txtを"、 "W"、STDOUT)。 gbtb; COUT <<(1 << 20)<< ENDL。 CIN >> N >> M >> K。 repd(I、1 、N) { CIN >> [I]。 } repd(I、1 、N) { LG [I] = LG [I / 2 ] + 1 。 } repd(I、1 、N) { [I] + = [I - 1 ]。 } int型POSと、 repd(I、0、20 ) { ST [N + 1 ] [I] = N + 1 。 } のための(int型 I = N; I> = 1 ; i-- ) { POS = UPPER_BOUND(A + 1、A + 1+ N [I - 1 ] + K) - 。 ST [i]が[ 0 ] = POS。 repd(J、1、20 ) { ST [I] [J] = ST [ST [I] [J - 1 ] [J - 1 ]。 } } int型のL、R。 repd(T、1 、M) { CIN >> L >> R。 POS = L。 int型 ANS = 0 ; 用(INT J = LG [R - L +1 ]; J> =0。j-- ) { 場合(ST [POS] [J] <= R) { POS = ST [POS] [J]。 ANS + =(1 << J)。 } } もし(ST [POS] [ 0 ] <= R) { COUT << " Chtholly " << ENDL。 } 他 { COUT << ANS + 1 << ENDL。 } } リターン 0; } インラインボイドのgetInt(int型 *のP){ チャーCH。 実行{ CH = GETCHAR()。 } 一方、(CH == ' ' || CH == ' \ n ' ); もし(CH == ' - ' ){ * P = - (GETCHAR() - ' 0 ' )。 一方、((CH = GETCHAR())> = ' 0 ' && CH <= ' 9 ' 10 - CH + ' 0 ' 。 } } 他{ * P = CH - ' 0 ' 。 一方、((CH = GETCHAR())> = ' 0 ' && CH <= ' 9 ' ){ * p = * P * 10 + CH - ' 0 ' 。 } } }