QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#543628 | #13. Router | 5un_xiaomivita_msg | 100 ✓ | 879ms | 18352kb | C++14 | 7.5kb | 2024-09-01 17:36:04 | 2024-09-01 17:36:04 |
Judging History
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;
}
詳細信息
Pretests
Final Tests
Test #1:
score: 10
Accepted
time: 1ms
memory: 3840kb
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: 158ms
memory: 15156kb
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: 175ms
memory: 15180kb
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: 0ms
memory: 3644kb
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: 0ms
memory: 3724kb
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: 3868kb
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: 450ms
memory: 15312kb
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: 660ms
memory: 16008kb
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: 879ms
memory: 17208kb
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: 850ms
memory: 18352kb
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