結果
問題 | No.430 文字列検索 |
ユーザー | yuppe19 😺 |
提出日時 | 2016-10-04 19:19:18 |
言語 | Java21 (openjdk 21) |
結果 |
CE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 7,684 bytes |
コンパイル時間 | 1,607 ms |
コンパイル使用メモリ | 80,440 KB |
最終ジャッジ日時 | 2024-11-10 00:09:02 |
合計ジャッジ時間 | 1,917 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
コンパイルメッセージ
Main.java:82: warning: [strictfp] as of release 17, all floating-point expressions are evaluated strictly and 'strictfp' is not required strictfp class MersenneTwister extends Random { // {{{ MersenneTwister ^ 1 error 1 warning
ソースコード
import java.io.*; import java.util.*; import static java.lang.Math.*; class FastScanner { // {{{ private final InputStream in = System.in; private final byte[] buffer = new byte[1024]; private int ptr = 0; private int buflen = 0; private boolean hasNextByte() { if(ptr < buflen) { return true; } ptr = 0; try { buflen = in.read(buffer); } catch(IOException ex) { ex.printStackTrace(); } if(buflen <= 0) { return false; } return true; } private int readByte() { if(hasNextByte()) { return buffer[ptr++]; } return -1; } private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126; } private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) { ptr++; } } public boolean hasNext() { skipUnprintable(); return hasNextByte(); } public String next() { if(!hasNext()) { throw new NoSuchElementException(); } StringBuilder sb = new StringBuilder(); int b = readByte(); while(isPrintableChar(b)) { sb.appendCodePoint(b); b = readByte(); } return sb.toString(); } public long nextLong() { if(!hasNext()) { throw new NoSuchElementException(); } long n = 0; boolean minus = false; int b = readByte(); if(b == '-') { minus = true; b = readByte(); } if(b < '0' || '9' < b) { throw new NumberFormatException(); } while(true) { if('0' <= b && b <= '9') { n *= 10; n += b - '0'; } else if(b == -1 || !isPrintableChar(b)) { return minus ? -n : n; } else { throw new NumberFormatException(); } b = readByte(); } } public int nextInt() { if(!hasNext()) { throw new NoSuchElementException(); } int n = 0; boolean minus = false; int b = readByte(); if(b == '-') { minus = true; b = readByte(); } if(b < '0' || '9' < b) { throw new NumberFormatException(); } while(true) { if('0' <= b && b <= '9') { n *= 10; n += b - '0'; } else if(b == -1 || !isPrintableChar(b)) { return minus ? -n : n; } else { throw new NumberFormatException(); } b = readByte(); } } } // }}} strictfp class MersenneTwister extends Random { // {{{ MersenneTwister private static final long serialVersionUID = -515082678588212038L; private final static int UPPER_MASK = 0x80000000; private final static int LOWER_MASK = 0x7fffffff; private final static int N = 624; private final static int M = 397; private final static int[] MAGIC = { 0x0, 0x9908b0df }; private transient int[] mt; private transient int mti; public MersenneTwister() { super(0L); setSeed(System.currentTimeMillis()); } public MersenneTwister(long seed) { super(seed); this.setSeed(seed); } public MersenneTwister(int[] buf) { super(0L); setSeed(buf); } private final void setSeed(int seed) { if(mt == null) { mt = new int[N]; } mt[0] = seed; for(mti=1; mti<N; ++mti) { mt[mti] = (1812433253 * (mt[mti-1] ^ (mt[mti-1] >>> 30)) + mti); } } public final synchronized void setSeed(long seed) { setSeed((int)seed); } public final synchronized void setSeed(int[] buf) { int length = buf.length; if(length == 0) { throw new IllegalArgumentException("buf is empty"); } int i = 1, j = 0, k = (N > length ? N : length); setSeed(19971007); for( ; k>0; --k) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >>> 30)) * 1664525)) + buf[j] + j; ++i; ++j; if(i >= N) { mt[0] = mt[N-1]; i = 1; } if(j >= length) { j = 0; } } for(k=N-1; k>0; --k) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >>> 30)) * 1566083941)) - i; ++i; if(i >= N) { mt[0] = mt[N-1]; i = 1; } } mt[0] = UPPER_MASK; } protected final synchronized int next(int bits) { int y, kk; if(mti >= N) { for(kk=0; kk<N-M; ++kk) { y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK); mt[kk] = mt[kk+M] ^ (y >>> 1) ^ MAGIC[y & 0x1]; } for( ; kk<N-1; ++kk) { y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK); mt[kk] = mt[kk+(M-N)] ^ (y >>> 1) ^ MAGIC[y & 0x1]; } y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK); mt[N-1] = mt[M-1] ^ (y >>> 1) ^ MAGIC[y & 0x1]; mti = 0; } y = mt[mti++]; y ^= (y >>> 11); y ^= (y << 7) & 0x9d2c5680; y ^= (y << 15) & 0xefc60000; y ^= (y >>> 18); return (y >>> (32 - bits)); } public int nextInt31() { return nextInt() >>> 1; } public long nextLong63() { return nextLong() >>> 1; } public <T> void shuffle(List<T> list) { int n = list.size(); for(int i=n-1; i>=1; --i) { int k = nextInt31() % (i + 1); if(k == i) { continue; } Collections.swap(list, k, i); } } } // }}} class MyUtil { private MyUtil() {} public static List<Long> segmentSieve(long a, long b) { int sqb = (int)sqrt(b); boolean[] isPrimeSmall = new boolean[sqb+1]; Arrays.fill(isPrimeSmall, true); isPrimeSmall[0] = isPrimeSmall[1] = true; boolean[] isPrime = new boolean[(int)(b-a)]; Arrays.fill(isPrime, true); isPrime[0] = a != 1; for(long i=2; i*i<b; ++i) { if(isPrimeSmall[(int)i]) { for(long j=2*i; j*j<b; j+=i) { isPrimeSmall[(int)j] = false; } for(long j=max(2, ((a+i-1)/i))*i; j<b; j+=i) { isPrime[(int)(j-a)] = false; } } } List<Long> res = new ArrayList<>(); for(long i=0; i<b-a; ++i) { if(isPrime[(int)i]) { res.add(i+a); } } return res; } } class RollingHash { private String s; private long[][] b, H; private long[] mods, bases; RollingHash(String s, long[] mods, long[] bases) { this.s = s; this.mods = mods; this.bases = bases; b = new long[2][0]; H = new long[2][0]; int n = s.length(); for(int j=0; j<2; ++j) { long B = bases[j] % mods[j]; b[j] = new long[n+1]; H[j] = new long[n+1]; b[j][0] = 1; H[j][0] = 0; for(int i=0; i<n; ++i) { b[j][i+1] = b[j][i] * B; b[j][i+1] %= mods[j]; H[j][i+1] = H[j][i] * B + (int)s.charAt(i); H[j][i+1] %= mods[j]; } } } long calcHash(int l, int r) { long h0 = (H[0][r] - b[0][r-l+1] * H[0][l-1]) % mods[0]; if(h0 < 0) { h0 += mods[0]; } long h1 = (H[1][r] - b[1][r-l+1] * H[1][l-1]) % mods[1]; if(h1 < 0) { h1 += mods[1]; } long hash = (h0 << 31) + h1; return hash; } } public class Main0430 { private void solve() { MersenneTwister mersenne = new MersenneTwister(); long LO = (long)pow(2L, 30), HI = LO + 100000; List<Long> primes = MyUtil.segmentSieve(LO, HI); mersenne.shuffle(primes); long[] mods = new long[] {primes.get(0), primes.get(1)}, bases = new long[] {mersenne.nextLong63(), mersenne.nextLong63()}; FastScanner sc = new FastScanner(); String s = sc.next(); RollingHash rhs = new RollingHash(s, mods, bases); int n = s.length(); long[][] cache = new long[11][n]; for(int len=1; len<=10; ++len) { for(int start=0; start+len<=n; ++start) { cache[len][start] = rhs.calcHash(start+1, start+len); } } int M = sc.nextInt(); int res = 0; for(int i=0; i<M; ++i) { String t = sc.next(); int m = t.length(); RollingHash rht = new RollingHash(t, mods, bases); long hasht = rht.calcHash(1, m); for(int start=0; start<n; ++start) { if(cache[m][start] == hasht) { ++res; } } } System.out.println(res); } public static void main(String[] args) { new Main0430().solve(); } }