QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#700579#13. RouterTheZone100 ✓863ms17920kbC++237.5kb2024-11-02 13:11:092024-11-02 13:11:09

Judging History

你现在查看的是最新测评结果

  • [2024-11-02 13:11:09]
  • 评测
  • 测评结果:100
  • 用时:863ms
  • 内存:17920kb
  • [2024-11-02 13:11:09]
  • 提交

answer

#include<bits/stdc++.h>
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int inf = 0x3f3f3f3f;

inline int getid(char c)
{
	return '0' <= c && c <= '9'? c - '0':
		'a' <= c && c <= 'z'? c - 'a' + 10:
		'A' <= c && c <= 'Z'? c - 'A' + 36:
		-1;
}

struct NFA
{
	vector< array<int,62> > g;
	vector< vector<int> > e;
	string s; int ptr;
	int allbeg, allenn;
	
	int new_Node(void)
	{
		g.emplace_back(); e.emplace_back();
		g.back().fill(-1);
		return (int)g.size() - 1;
	}
	void makeRegexp(int beg,int enn)
	{
		// eprintf("makeRegexp, ptr = %d\n",ptr);
		while(ptr < (int)s.size() && s[ptr] != ')')
		{
			int u = new_Node(); makeAlternative(u, enn);
			e[beg].push_back(u);
			if(ptr < (int)s.size() && s[ptr] == '|') ++ptr;
		}
		// eprintf("finish Regexp, ptr = %d\n",ptr);
	}
	void makeAlternative(int beg,int enn)
	{
		// eprintf("makeAlternative, ptr = %d, s[ptr] = %c\n",ptr,s[ptr]);
		while(ptr < (int)s.size() && (getid(s[ptr]) != -1 || s[ptr] == '[' || s[ptr] == '('))
		{
			int u = new_Node(); makeTerm(beg, u);
			beg = u;
		}
		e[beg].push_back(enn);
		// eprintf("finish Alternative, ptr = %d\n",ptr);
	}
	void makeTerm(int beg,int enn)
	{
		// eprintf("makeTerm, ptr = %d, beg = %d, enn = %d\n",ptr,beg,enn);
		int mid = ptr, cnt = 0;
		while(1)
		{
			if(s[mid] == '[' || s[mid] == '(')
				++cnt;
			if(s[mid] == ']' || s[mid] == ')')
				--cnt;
			if(!cnt) break;
			++mid;
		}
		++mid;
		// eprintf("mid = %d\n",mid);
		if(s[mid] != '{')
		{
			makeAtom(beg, enn);
			return;
		}
		
		int l = 0, r = 0;
		while(s[++mid] != ',') l = l * 10 + s[mid] - '0';
		while(s[++mid] != '}') r = r * 10 + s[mid] - '0';
		
		// eprintf("l = %d, r = %d, mid = %d\n",l,r,mid);
		
		int save = ptr;
		vector<int> pos(l+1);
		pos[0] = new_Node();
		e[beg].push_back(pos[0]);
		for(int i=1; i<=l; ++i)
		{
			pos[i] = new_Node();
			ptr = save; makeAtom(pos[i-1], pos[i]);
		}
		
		// eprintf("ok l = %d, r = %d\n",l,r);
		
		if(s[mid-1] == ',')
		{
			if(l >= 1)
			{
				e[pos[l]].push_back(pos[l-1]);
				e[pos[l]].push_back(enn);
			}
			else
			{
				ptr = save;
				int u = new_Node();
				makeAtom(pos[0], u);
				e[pos[0]].push_back(u);
				e[u].push_back(pos[0]);
				e[u].push_back(enn);
			}
		}
		else
		{
			pos.resize(r+1);
			for(int i=l+1; i<=r; ++i)
			{
				pos[i] = new_Node();
				ptr = save; makeAtom(pos[i-1], pos[i]);
				e[pos[i-1]].push_back(enn);
			}
			e[pos[r]].push_back(enn);
		}
		ptr = mid + 1;
		// eprintf("finish Term, ptr = %d\n",ptr);
	}
	void makeAtom(int beg,int enn)
	{
		// eprintf("makeAtom, ptr = %d\n",ptr);
		if(s[ptr] == '(')
			++ptr, makeRegexp(beg, enn), ++ptr;
		else if(s[ptr] == '[')
		{
			int l = s[ptr+1];
			while(s[ptr] != ']') ++ptr;
			int r = s[ptr-1]; ++ptr;
			for(int i=l; i<=r; ++i)
				g[beg][getid(i)] = enn;
		}
		else
		{
			g[beg][getid(s[ptr])] = enn;
			++ptr;
		}
	}
	void build(string _s)
	{
		g.clear(); e.clear();
		s = _s; ptr = 0;
		allbeg = new_Node(); allenn = new_Node();
		makeRegexp(allbeg, allenn);
	}
	void dfs_e(int u,set<int> &cur)
	{
		if(!cur.emplace(u).second) return;
		for(int v: e[u])
			dfs_e(v, cur);
	}
	bool match(string t)
	{
		// eprintf("match my = %s, oth = %s\n",s.c_str(),t.c_str());
		// eprintf("allbeg = %d, allenn = %d\n",allbeg,allenn);
		set<int> cur;
		dfs_e(allbeg, cur);
		for(char c: t)
		{
			int cid = getid(c);
			// for(auto u: cur)
			// 	eprintf("cur: %d\n",u);
			// eprintf("add c = %c, id = %d\n",c,cid);
			set<int> nxt;
			for(int u: cur)
			{
				int v = g[u][cid];
				// eprintf("walk %d -> %d\n",u,v);
				if(v != -1) dfs_e(v, nxt);
			}
			cur.swap(nxt);
			if(!cur.size()) break;
		}
		// for(auto u: cur)
		// 	eprintf("cur: %d\n",u);
		return cur.find(allenn) != cur.end();
	}
}nfa[60];

map<string,int> name_to_nfa;
string nfa_to_name[60];
int totnfa = 0;

vector<string> splitRoute(string s)
{
	vector<string> res;
	int l = 0;
	for(int i=1; i<(int)s.size(); ++i)
	{
		if(s[i] == '/')
			res.emplace_back(s.begin() + l + 1, s.begin() + i), l = i;
	}
	res.emplace_back(s.begin() + l + 1, s.end());
	return res;
}

namespace Trie
{
	vector< map<string,int> > tr;
	vector< array<int,60> > tr_nfa;
	vector< string > name;
	
	int new_Node(void)
	{
		tr.emplace_back(); tr_nfa.emplace_back(); name.emplace_back();
		tr_nfa.back().fill(-1);
		return (int)tr.size() - 1;
	}
	void init(void)
	{
		tr.clear(); tr_nfa.clear(); name.clear();
		new_Node();
	}
	void insert(string _s,string _name)
	{
		auto s = splitRoute(_s);
		int u = 0;
		for(auto t: s)
		{
			if(t[0] == ':')
			{
				int id;
				auto tt = t.substr(1);
				if(!name_to_nfa.count(tt))
				{
					id = name_to_nfa[tt] = totnfa;
					nfa_to_name[totnfa] = tt;
					++totnfa;
				}
				else
				{
					id = name_to_nfa[tt];
				}
				
				int v = tr_nfa[u][id];
				if(v == -1) v = new_Node(), tr_nfa[u][id] = v;
				u = v;
			}
			else
			{
				int v;
				if(tr[u].count(t))
					v = tr[u][t];
				else
					v = tr[u][t] = new_Node();
				u = v;
			}
		}
		name[u] = _name;
	}
	void query(string _s)
	{
		auto s = splitRoute(_s);
		map< string, vector<string> > para;
		
		string saveback;
		{
			int pos = s.back().find('?');
			if(pos != -1)
			{
				saveback = s.back().substr(pos+1);
				s.back().resize(pos);
			}
		}
		
		// eprintf("\nquery: ");
		// for(auto t: s)
		// 	eprintf("<%s> ",t.c_str());
		// eprintf("\n");
		
		int u = 0;
		for(auto t: s)
		{
			int v = -1;
			if(tr[u].count(t))
			{
				v = tr[u][t];
			}
			else
			{
				for(int i=0; i<totnfa; ++i)
				{
					// eprintf("try u = %d, id = %d, v = %d\n",u,i,tr_nfa[u][i]);
					if(tr_nfa[u][i] != -1 && nfa[i].match(t))
					{
						para[ nfa_to_name[i] ].push_back(t);
						v = tr_nfa[u][i];
						break;
					}
				}
			}
			if(v == -1)
			{
				cout << "404 Not Found\n";
				return;
			}
			u = v;
		}
		if(name[u].size() == 0)
		{
			cout << "404 Not Found\n";
			return;
		}
		
		if(saveback.size())
		{
			for(char &c: saveback)
				if(getid(c) == -1)
					c = ' ';
			
			stringstream tt(saveback);
			vector<string> vec;
			for(string x; tt>>x;)
				vec.emplace_back(x);
			
			for(int i=0; i+1<(int)vec.size(); i+=2)
				para[vec[i]].push_back(vec[i+1]);
		}
		
		cout << "Request matches action \"" << name[u] << "\" with parameters {";
		
		bool isfir = 1;
		for(auto it: para)
		{
			if(!isfir) cout << ',';
			isfir = 0;
			
			cout << "\"" << it.first << "\":";
			auto &vec = it.second;
			if(vec.size() == 1)
			{
				cout << "\"" << vec[0] << "\"";
			}
			else
			{
				cout << '[';
				cout << "\"" << vec[0] << "\"";
				for(int i=1; i<(int)vec.size(); ++i)
					cout << ",\"" << vec[i] << "\"";
				cout << ']';
			}
		}
		cout << "}\n";
	}
}

void solve(int testid)
{
	cout << "Case #" << testid << ":\n";
	
	Trie::init();
	name_to_nfa.clear(); totnfa = 0;
	
	int n;
	cin >> n;
	for(int i=1; i<=n; ++i)
	{
		string s, name;
		cin >> s >> name;
		Trie::insert(s, name);
	}
	
	for(int i=0; i<totnfa; ++i)
	{
		string x,y;
		cin >> x >> y;
		// eprintf("(%s).build(%s)\n",x.c_str(),y.c_str());
		nfa[ name_to_nfa[x] ].build(y);
	}
	
	int Q;
	cin >> Q;
	while(Q--)
	{
		string s;
		cin >> s;
		Trie::query(s);
	}
}

int main(void)
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int T;
	cin >> T;
	for(int i=1; i<=T; ++i)
		solve(i);
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Pretests


Final Tests

Test #1:

score: 10
Accepted
time: 1ms
memory: 3644kb

input:

1
4
/user/show
userShow
/user/edit
userEdit
/user/delete
userDelete
/message/send
messageSend
8
/user/show?handle=WJMZBMR
/user/edit?handle=WJMZBMR&type=doubi
/user/show2?handle=WJMZBMR
/user/delete?handle=WJMZBMR
/message/send?from=GuyUpLion&to=WJMZBMR&content=nishishabi
/sudo/user/deleteAll?force=...

output:

Case #1:
Request matches action "userShow" with parameters {"handle":"WJMZBMR"}
Request matches action "userEdit" with parameters {"handle":"WJMZBMR","type":"doubi"}
404 Not Found
Request matches action "userDelete" with parameters {"handle":"WJMZBMR"}
Request matches action "messageSend" with param...

result:

ok 9 lines

Test #2:

score: 10
Accepted
time: 169ms
memory: 15028kb

input:

5
20000
/Oo/pt/GI/7eSZo
GaWpHfuwXZ
/Oo/pt/GI/2fD4N
PelOZXZAdJ
/Oo/pt/GI/Fneu7
GRNGPVcQUD
/Oo/pt/GI/ff1OJ
YnLFicuZwm
/Oo/pt/GI/2YjXS
xeJnUIvjZf
/Oo/pt/GI/WEbeB
dfDQvEfExS
/Oo/pt/GI/UbdVz
znwCWkROhG
/Oo/pt/GI/MVncl
SbIoWskvhP
/Oo/pt/GI/t37hx
LmJAlDmtUs
/Oo/pt/GI/bdx1b
BMMmjHOTYt
/Oo/pt/GI/VkVdo
BZqDmn...

output:

Case #1:
Request matches action "qryXhOAkdN" with parameters {}
Request matches action "WdLaIPgxLe" with parameters {"BeA":"cC7D","EtX":"27vv","kIz":"KrMG"}
404 Not Found
404 Not Found
404 Not Found
404 Not Found
Request matches action "LMgsDMAtVl" with parameters {"FvU":"blOL","LCR":"iXzR","Mlk":"Q...

result:

ok 100005 lines

Test #3:

score: 10
Accepted
time: 173ms
memory: 14360kb

input:

5
20000
/mT/kR/E7/nf7mU
DtXyJptWQE
/mT/kR/E7/HbMdw
CInmqffDmM
/mT/kR/E7/UwmxK
nhKDxbSBoH
/mT/kR/E7/QPWxn
hPnPoWNeeW
/mT/kR/E7/nO0wW
wjKYbvenJJ
/mT/kR/E7/A9FO5
lVhKuozrNs
/mT/kR/E7/sauoC
TghZLVCkbg
/mT/kR/E7/7OhtX
WvPSUjCneI
/mT/kR/E7/NaC3w
fRClfNGnPI
/mT/kR/E7/KVt5P
BAZrgwzBXb
/mT/kR/E7/5ma44
FhEBYy...

output:

Case #1:
Request matches action "NAwUKiVdkz" with parameters {"BCb":"uIAS","Bqx":"YL1q","RZT":"UT33","kDU":"edgN"}
Request matches action "RVnVUywRFD" with parameters {}
404 Not Found
404 Not Found
404 Not Found
404 Not Found
Request matches action "dUfdJhrOeU" with parameters {"TvA":"LixU","VFR":"r...

result:

ok 100005 lines

Test #4:

score: 10
Accepted
time: 1ms
memory: 3692kb

input:

3
3
/user/:id/show
userShow
/message/list
messageList
/message/:id/show
messageShow
id [0-9]{2,4}
3
/message/list
/user/123/show?avatar=true
/message/5312/show?page=1
1
/foo/:id/:bar/:bar
fun
id [0-9]{2,4}
bar [a-z]{1,3}
1
/foo/777/az/bc?bar=xyz&bar=zzz
2
/user/:handle/show
userShow
/user/:id/show
u...

output:

Case #1:
Request matches action "messageList" with parameters {}
Request matches action "userShow" with parameters {"avatar":"true","id":"123"}
Request matches action "messageShow" with parameters {"id":"5312","page":"1"}
Case #2:
Request matches action "fun" with parameters {"bar":["az","bc","xyz",...

result:

ok 11 lines

Test #5:

score: 10
Accepted
time: 1ms
memory: 3916kb

input:

2
5
/user/:userHandle/show
userShow
/user/:userHandle/edit
userEdit
/message/send
messageSend
/message/:messageId/show
messageShow
/user/:userHandle/setBirthday/:date
userSetBirthday
userHandle ([A-Z]|[a-z]){4,10}
messageId ([a-z]|[0-9]){8,8}
date (19[0-9]{2,2}|200[0-9]|201[0-4])(0[1-9]|1[0-2])
15
/...

output:

Case #1:
Request matches action "userShow" with parameters {"userHandle":"crash"}
404 Not Found
Request matches action "userEdit" with parameters {"type":"doubi","userHandle":"WJMZBMR"}
Request matches action "userShow" with parameters {"avatar":"true","userHandle":"WJMZBMR"}
Request matches action ...

result:

ok 24 lines

Test #6:

score: 10
Accepted
time: 0ms
memory: 3960kb

input:

1
9
/a/:expA
testA
/b/:expB
testB
/c/:expC
testC
/d/:expD
testD
/e/:expE
testE
/f/:expF
testF
/g/:expG
testG
/h/:expH
testH
/i/:expI
testI
expA a([b-c]{0,})(c{1,}d)
expB a([b-c]{0,})c{0,}
expC (a|b|c|d|e)f
expD a{1,}b{1,}c
expE (((((((((a)))))))))
expF a[b-d]e
expG (ab{4,5}){0,1}bc
expH (a{1,}|b){1,...

output:

Case #1:
Request matches action "testA" with parameters {"expA":"acd"}
404 Not Found
Request matches action "testA" with parameters {"expA":"accd"}
404 Not Found
Request matches action "testA" with parameters {"expA":"abbbccbbcbcd"}
Request matches action "testB" with parameters {"expB":"a"}
Request...

result:

ok 40 lines

Test #7:

score: 10
Accepted
time: 464ms
memory: 15720kb

input:

5
20000
/:d/Xa/pF/qR/AHOJi
KcioVpFutT
/:B/Xa/pF/qR/vPS8a
olfLwawkjj
/:h/Xa/pF/qR/F9pAn
DlvayDMhBr
/:X/Xa/pF/qR/dbiqh
hgWRSuyKJb
/:B/Xa/pF/qR/bYxcI
NMAhONaRqV
/:w/Xa/pF/qR/sUqgS
jnwOPhLTBc
/:e/Xa/pF/qR/jbDTg
OYXysAcgaI
/:a/Xa/pF/qR/nkDlc
MmCDeWkbOh
/:m/Xa/pF/qR/3Fu9U
IWsFasuAYF
/:r/Xa/pF/qR/GBJqj
Udl...

output:

Case #1:
404 Not Found
404 Not Found
Request matches action "XCOwpXeehZ" with parameters {"J":"JRj","Ttq":"sste","pLg":"6I7n"}
Request matches action "FwqgIOXQtx" with parameters {"AMy":"60KP","L":"LxX","QKC":"hXVY","pjN":"yRYY"}
404 Not Found
Request matches action "ORqyPOphpD" with parameters {"G"...

result:

ok 100005 lines

Test #8:

score: 10
Accepted
time: 651ms
memory: 15164kb

input:

5
20000
/:p/AG/I2/:W/qR/yR/WQp1B
OMguaUOWeL
/:X/AG/I2/:j/qR/yR/LExvw
ruPRaSFReN
/:f/AG/I2/:R/qR/yR/h69ms
mZeBvBQGPt
/:S/AG/I2/:L/qR/yR/wqMnI
mTAgDZIBZn
/:K/AG/I2/:u/qR/yR/kH2fk
liGLUxZthV
/:r/AG/I2/:N/qR/yR/AOZUz
vvywfMeRgD
/:e/AG/I2/:P/qR/yR/aR1Ub
IdxTrlllRD
/:i/AG/I2/:D/qR/yR/F70ob
bdERKpqhRA
/:c/...

output:

Case #1:
404 Not Found
Request matches action "UJzLRpXcUj" with parameters {"T":"TWw","v":"vlM"}
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
Request matches action "iMRSvVsKSv" with parameters {"L":"LfF","P":"PuhY","Whi":"aZEY","kkj":"vffu","ofH"...

result:

ok 100005 lines

Test #9:

score: 10
Accepted
time: 846ms
memory: 17920kb

input:

5
20000
/:W/Qf/ZL/:S/ok/Pz/vTPCO
tTkHRaRZOl
/:y/Qf/ZL/:O/ok/Pz/GXn08
IyKwbtDosO
/:m/Qf/ZL/:b/ok/Pz/Yo5aY
MyqsYbMazS
/:y/Qf/ZL/:W/ok/Pz/ohE9i
yCdMJvQuei
/:b/Qf/ZL/:y/ok/Pz/mSLAu
SnVLmwLWHv
/:w/Qf/ZL/:S/ok/Pz/e2uK0
pKIGBMNGKW
/:B/Qf/ZL/:J/ok/Pz/6QCz6
CXMuvGooBL
/:W/Qf/ZL/:l/ok/Pz/FvMe5
mcaSoGnfmS
/:C/...

output:

Case #1:
404 Not Found
404 Not Found
Request matches action "PUECawPkdL" with parameters {"ddC":"p7aW","e":"ewA","tSn":"SpjF","y":"y","yIh":"XUcc","yac":"PXA3"}
404 Not Found
Request matches action "tWONOjhdZa" with parameters {"F":"F","qqV":"q2RY","u":"u"}
Request matches action "MDjliQiVbq" with p...

result:

ok 100005 lines

Test #10:

score: 10
Accepted
time: 863ms
memory: 17484kb

input:

5
20000
/:M/hP/QZ/:b/xN/mD/fH1G5
JHPsElQRqL
/:Q/hP/QZ/:c/xN/mD/UfLUT
wisHKFtBQg
/:O/hP/QZ/:p/xN/mD/nHH8x
opUNFZFexx
/:S/hP/QZ/:N/xN/mD/6ricK
tNIcIMuMzZ
/:x/hP/QZ/:i/xN/mD/wLNM3
qlrVWOLgqJ
/:Q/hP/QZ/:T/xN/mD/SUqgU
SREHWjveiD
/:M/hP/QZ/:p/xN/mD/LdLlM
UIctkUvzse
/:E/hP/QZ/:A/xN/mD/4IzTw
gibBlpIuOC
/:a/...

output:

Case #1:
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
404 Not Found
Request matches action "LyharhUmMM" with parameters {"D":"D","f":"f2w","gFf":"kde2","kpw":"OvUn","mQB":"4Si4"}
404 Not Found
404 Not Foun...

result:

ok 100005 lines