QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#700579 | #13. Router | TheZone | 100 ✓ | 863ms | 17920kb | C++23 | 7.5kb | 2024-11-02 13:11:09 | 2024-11-02 13:11:09 |
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: 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