リンク:https://ac.nowcoder.com/acm/contest/884/K
出典:牛オフネットワーク
タイトル説明
300iqは、300の倍数である数字を愛しています。
ある日、彼は、文字列が数字で構成されました。彼は十進整数として考えたときに、文字列の多くの部分文字列は、300の倍数であるかを知りたいです。
先頭と末尾のゼロは許可されていることに注意してください(両方とも元の文字列と部分文字列にあなたが選んだ)
と異なる場所に出現する同じ部分には、複数回カウントすることができます。
説明を入力します。
文字列からなる単一の行が「9」に文字「0」から成っていました。
出力説明:
倍数である部分文字列の数十進整数として考えたときに300。
解決策:まず、我々は条件が満たされた分析:300ストリングで割り切れる
最後の2つの確かに00の1列
確かにあなたの2.フロントと3で割り切れる
ので、私たちは、レコード「iビットとのmod 3ケースの前に」変数sumを、開くことができます。和== 0、和== 1:3例があり 、和== 2
アレイを開くために、CNT []、「私は、フロントケース3 MODが発生している数」記録は。そののみ記録されるCNT [0]、CNT [1 ]、CNT [2]
なぜ記録ケース1と2、それ?たとえば、次の
和Rの和L場合と同じで、[L、R&LT]間隔で、それはL〜Rおよび[LであるMOD 3 == 0のビットの数のことを意味します、 R]は3つのサブ分割することができる配列です。
// の#pragmaコメント(リンカー、 "/ STACK:1024000000,1024000000") // の#pragma GCC最適化(2) // の#include <ビット/ STDC ++ H> の#include <アルゴリズム> の#include <iostreamの> する#include < fstreamの> の#include <sstream提供> の#include <反復子> の#include <CStringの> する#include < ストリング > の#include <cmath> の#include <cstdioを> する#include <CCTYPE> の#include <ベクトル> の#include <両端キュー> する#include <キュー> の#include <スタック> の#include <マップ> 書式#include <リスト> の#include < 設定 > 使用して名前空間はstdを、 typedefを倍増DOU。 typedefの長い長いLL。 typedefのペア < int型、int型 > PII。 マップのtypedef < int型、int型 > MII; #define PAI ACOS(-1.0) の#define M 100005 の#define 0x3f3f3f3f INF の#define MOD十億七 の#define左K << 1つ の#define右K << 1つの| 1つ の#define LSONのL、中、左 の#define中間+ 1 rson、R、右 の#define W(a)は(A) の#define MS(B)のmemset(A、B、はsizeof(A)) の#define ABS(A )(^(>> 31)) - (>> 31)チャーSTR [M]。 int型CNT [M]; int型のmain() { IOS :: sync_with_stdio(偽); cin.tie(nullptr)、cout.tie(nullptr)。 W(CIN >> STR){ LL ANS = 0 。 INT LEN = STRLEN(STR)。 以下のために(int型私は= 0 ; iがLEN <; I ++ ){ IF(STR [I] ==は、' 0 ')ANS ++; // 最初の個々のケースを数える0 } CNT [ 0 ] = 1 ; int型 SUM = 0 ; // 3ビットのI MOD値の前 のために(int型 Iを= 0 ; IがLEN <; I ++は){ SUM + STR = [I] - ' 0 ' ; SUM%= 3 ; IFが(私は+ 。1 <LEN && STR [I] == ' 0 ' && STR [I +1 ] == ' 0 '){ // 満足00との長さ以内に終了 ANS + = CNT [SUM]; } CNT [SUM] ++; // CNT [0]、CNT [1]、CNT [ 2] } COUT << ANS << ENDL; } 戻り 0 ; }