# 題解 ### [atcoder ABC 363F - Palindromic Expression](https://atcoder.jp/contests/abc363/tasks/abc363_f) 注意到如果要分解出兩個數字塞在前後 其中一個數字一定會 $\le \sqrt{n}$ 那可以用遞迴的方式 `dfs(n) = i*dfs(n/(i*j))*j` 其中 $j=rev(i)$ 且 $i$ 跟 $j$ 都不包含 $0$ 那要怎麼證複雜度是好的? 首先要記憶化遞迴結果 ~~然後丟上去就發現過了呵呵~~ 我猜複雜度是好的 我也不會證明 code: ```C++ #include <bits/stdc++.h> using namespace std; using ll = long long; #define int ll #pragma GCC optimize("Ofast") inline bool ip(int n) { string str=to_string(n); int l=0, r=str.size()-1; while(l<r) { if(str[l]!=str[r]) return false; l++, r--; } return true; } inline int rev(int n) { string str=to_string(n); reverse(str.begin(), str.end()); return stoll(str); } inline bool hz(string str) { for(auto& e : str) { if(e=='0') { return true; } } return false; } map<int, string> ms; string dfs(int n) { if(ms.count(n)) return ms[n]; if(ip(n) && !hz(to_string(n))) return to_string(n); for(int i=2;i*i<=n;i++) { if(hz(to_string(i))) continue; int j=rev(i); if(n%(i*j)==0) { string next=dfs(n/(i*j)); ms[n/(i*j)]=next; if(next!="-1" && !hz(next)) { return (string)(to_string(i) + "*" + next + "*" + to_string(j)); } } } return "-1"; } signed main() { ios::sync_with_stdio(0); cin.tie(0); int n; cin >> n; cout << dfs(n); } ``` ### [atcoder ABC 377F - Avoid Queen Attack](https://atcoder.jp/contests/abc377/tasks/abc377_f) 注意到$M$很小所以可以$M^2$取交點 依舊實作地獄QAO ```C++ #include <bits/stdc++.h> using namespace std; using ll = long long; #define int ll #pragma GCC optimize("Ofast") signed main() { ios::sync_with_stdio(0); cin.tie(0); int n, m, ans, a, b; cin >> n >> m; ans=n*n; set<int> rs, cs, ds1, ds2; while(m--) { cin >> a >> b; ans-=n; if(rs.count(a)) ans+=n; else { set<int> tmp; for(auto& e : cs) tmp.insert(e); for(auto& e : ds1) if(e-a>0 && e-a<=n) tmp.insert(e-a); for(auto& e : ds2) if(a-e>0 && a-e<=n) tmp.insert(a-e); ans+=tmp.size(); } rs.insert(a); ans-=n; if(cs.count(b)) ans+=n; else { set<int> tmp; for(auto& e : rs) tmp.insert(e); for(auto& e : ds1) if(e-b>0 && e-b<=n) tmp.insert(e-b); for(auto& e : ds2) if(b+e>0 && b+e<=n) tmp.insert(b+e); ans+=tmp.size(); } cs.insert(b); int mx=a+b-1; if(mx>n) mx=2*n+1-a-b; ans-=mx; if(ds1.count(a+b)) ans+=mx; else { set<pair<int, int>> tmp; for(auto& e : rs) if(a+b-e>0 && a+b-e<=n) tmp.insert({e, a+b-e}); for(auto& e : cs) if(a+b-e>0 && a+b-e<=n) tmp.insert({a+b-e, e}); for(auto& e : ds2) if((e+a+b)%2==0 && (e+a+b)/2>0 && (e+a+b)/2<=n && a+b-(e+a+b)/2>0 && a+b-(e+a+b)/2<=n) tmp.insert({(e+a+b)/2, a+b-(e+a+b)/2}); ans+=tmp.size(); } ds1.insert(a+b); mx=n-abs(a-b); ans-=mx; if(ds2.count(a-b)) ans+=mx; else { set<pair<int, int>> tmp; for(auto& e : rs) if(e-a+b>0 && e-a+b<=n) tmp.insert({e, e-a+b}); for(auto& e : cs) if(a-b+e>0 && a-b+e<=n) tmp.insert({a-b+e, e}); for(auto& e : ds1) if((e+a-b)%2==0 && (e+a-b)/2>0 && (e+a-b)/2<=n && e-(e+a-b)/2>0 && e-(e+a-b)/2<=n) tmp.insert({(e+a-b)/2, e-(e+a-b)/2}); ans+=tmp.size(); } ds2.insert({a-b}); } cout << ans; } ```
{"title":"題解","description":"注意到如果要分解出兩個數字塞在前後其中一個數字一定會 \\le \\sqrt{n}","contributors":"[{\"id\":\"8ef74834-8c0e-4ca4-a3d6-02428329176f\",\"add\":3125,\"del\":0,\"latestUpdatedAt\":1766565119655}]"}
Expand menu