掃黃機器人

謝一

製作動機

實體掃黃

線上掃黃

掃黃機制

建立字典

字串匹配

HASH

\(Hash(S) = S_0 * r^0 + S_1 * r^1 + \dots + S_n * r^n \ mod P\)

檢查 hash 值是否一樣就能判斷兩個字串是否相同

重疊問題?

檢查輸出字串中包含時:

import discord
r, mod = 283, 2147483647;
T = open("token.txt", 'r').read();
keyword = open("keyword.txt", 'r').read().split();
KW = [];
ints = discord.Intents.all();
bot = discord.Client(intents = ints);
def cut(S : str):
	T = "";
	for s in S:
		if ord(s) < 128 and (ord(s) < ord('a') or ord(s) > ord('z')):
			continue;
		else:
			T += s;
	return T;
def has(S : str):
	E = [];
	h, j, k, x = 0, 0, 0, 1;
	for i in range(len(S)):
		if S[i] >= 'a' and S[i] <= 'z':
			E.append(j);
			j += 1;
		else:
			j += 3;
	j = 0;
	S = S.encode("utf-8");
	for i in range(len(S)):
		if k < len(E) and i == E[k]:
			h = (h + (S[i] + 256) * x) % mod;
			k += 1;
		else:
			h = (h + S[i] * x) % mod;
		x = x * r % mod;
		j += 1;
	return [h, j];
def hsh(S : str):
	E, H = [], [0];
	j, k, x = 0, 0, 1;
	for i in range(len(S)):
		if S[i] >= 'a' and S[i] <= 'z':
			E.append(j);
			j += 1;
		else:
			j += 3;
	j = 0;
	S = S.encode("utf-8");
	for i in range(len(S)):
		if k < len(E) and i == E[k]:
			H.append((H[i] + (S[i] + 256) * x) % mod);
			k += 1;
		else:
			H.append(((H[i] + S[i] * x)) % mod);
		x = x * r % mod;
	return H;
def yellow(msg : str):
	S = hsh(msg);
	for [k, w] in KW:
		for i in range(1, len(S) - w + 1):
			if k == (S[i + w - 1] - S[i - 1] + mod) % mod:
				return 1;
			k = k * r % mod;
	return 0;
@bot.event
async def on_ready():
	for kw in keyword:
		KW.append(has(kw));
	print("logged in as", end = ' ');
	print(bot.user);
@bot.event
async def on_message(msg : discord.Message):
	if msg.author == bot.user:
		return;
	M = msg.content;
	M = cut(M.lower());
	if yellow(M):
		print("業績 + 1");
		await msg.channel.send(file = discord.File("swipe.png"));
		await msg.channel.send(file = discord.File("yellow.png"));
if __name__ == "__main__":
	bot.run(T);

實測時間

掃黃!!!

DigoliangSchrödingerAlive

Def: \(u \xrightarrow{k} v\) = the count of different paths starting from \(u\) ending at \(v\) through exactly \(k\) edges

Let \(G\) be the original adjacency matrix, then \(G^n[i][j]\) = \(i \xrightarrow{n} j\)

 

\(G^n[i][j] = \sum_{k = 1}^{N}{G^{(n - 1)}[i][k] \times G[k][j]}\)

\(u \xrightarrow{k + 1} v = \sum_{w \in V}^{}(u \xrightarrow{k} w)(w \xrightarrow{1} v)\)

Time Complexity

Time = Matrix multiplication \(\times\) multiplication count = \(\mathcal{O}(N^3) \times \mathcal{O}(K) = \mathcal{O}(N^3K)\)

Since the multiplication of matrices have associative property, so \(G^n = (G^{\frac{n}{2}})^2\)

\(\implies\) multilication count \(\mathcal{O}(K) \to \mathcal{O}(\lg{K})\)

\(\implies\) time complexity = \(\mathcal{O}(N^3\lg{K})\)

Speed up

Code

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1919810513;
array<array<int, 120>, 120> G;
array<array<int, 120>, 120> mul(int n, array<array<int, 120>, 120> &A, array<array<int, 120>, 120> &B){
	array<array<int, 120>, 120> C;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= n; j++){
			C[i][j] = 0;
			for(int k = 1; k <= n; k++) C[i][j] += A[i][k] * B[k][j] % mod;
			C[i][j] %= mod;
		}
	}
	return C;
}
array<array<int, 120>, 120> hayahayahatimi(int n, int k){
	array<array<int, 120>, 120> P;
	for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) P[i][j] = (i == j);
	for(int i = 1; i <= k; i <<= 1){
		if(i & k) P = mul(n, P, G);
		G = mul(n, G, G);
	}
	return P;
}
signed main(){
	int n, m, k, u, v;
	cin >> n >> m >> k;
	while(m--){
		cin >> u >> v;
		G[u][v] = 1;
	}
	array<array<int, 120>, 120> P = hayahayahatimi(n, k);
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= n; j++) cout << P[i][j] << " \n"[j == n];
	}
	return 0;
}
Made with Slides.com