[TIOJ]1998. 網路遮罩
題目連結:http://tioj.ck.tp.edu.tw/problems/1998
可以把字串處理成數字,先排序左界,二分搜找最後一個小於等於該數字的位置,所有左界小於等於詢問的數字便在此位置的前綴,因此只要維護前綴最大值即可。
可以把字串處理成數字,先排序左界,二分搜找最後一個小於等於該數字的位置,所有左界小於等於詢問的數字便在此位置的前綴,因此只要維護前綴最大值即可。
#include <bits/stdc++.h> #define PB push_back #define F first #define S second #define lld long long #define jizz cin.tie(0);ios_base::sync_with_stdio(0); #define endl '\n' using namespace std; typedef pair<lld,lld> Pair; lld tmp,t,p; string s; vector<Pair> v; bool find(lld t){ int l = 0,r = v.size(); while(r-l != 1){ int M = (l+r)/2; if(v[M].F > t)r = M; else l = M; } return v[l].F <= t && v[l].S >= t; } int main(){jizz int n,m;cin >> n >> m; for(int i = 0 ; i < n ;i ++){ cin >>s; tmp = 0,t = 0; for(int i = 0 ; i < s.size(); i++){ if(s[i] == '.')t <<= 8,t += tmp,tmp = 0; else if(s[i] >= '0' && s[i] <= '9')tmp *= 10,tmp += s[i]-'0'; else if(s[i] == '/'){ t <<= 8,t += tmp,p = i,tmp = 0; break; } } for(int j = p+1; j < s.size(); j++)tmp *= 10,tmp += s[j]-'0'; t >>= (32-tmp); lld e = (t << (32-tmp)); for(int i = 0 ; i <(32-tmp); i++)t <<= 1,t++; v.PB({e,t}); } sort(v.begin(),v.end()); for(int i = 1 ; i < v.size() ; i++)v[i].S = max(v[i].S,v[i-1].S); while(m--){ cin >>s; s += '.'; tmp = 0,t = 0; for(int i = 0 ; i < s.length(); i++){ if(s[i] == '.')t <<= 8,t += tmp,tmp = 0; else if(s[i] >= '0' &&s[i] <= '9')tmp *= 10,tmp += s[i]-'0'; } cout << (find(t) ? "TRUE" : "FALSE") << endl; } return 0; }
留言
張貼留言