Skip to content

Commit 5d56504

Browse files
committed
Runtime 1356 ms (Top 14.54%) | Memory 220.0 MB (Top 9.9%)
1 parent 275216c commit 5d56504

File tree

1 file changed

+56
-51
lines changed

1 file changed

+56
-51
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,64 @@
1-
// Runtime: 1534 ms (Top 45.54%) | Memory: 199 MB (Top 25.74%)
21
class Solution {
2+
vector<int> st;
33
public:
4-
map<pair<int, int>, int>edgeCount;
5-
vector<int>degree;
6-
7-
vector<int> countPairsHelper(vector<int>&indegree, vector<int>&queries, int n){
8-
vector<int>ans;
9-
10-
// for each query, time: O(2*n) for two pointer and O(uniqueEdgesCount)
11-
for(int query: queries){
12-
// two pointer
13-
int i = 0, j = n-1, total = 0;
14-
while(i != j){
15-
if(degree[i] + degree[j] > query){
16-
j--;
17-
}
18-
else{
19-
total += (n-j-1);
20-
i++;
21-
}
22-
}
23-
while(i < n){
24-
total += (n-i-1);
25-
i++;
26-
}
27-
28-
// remove the negative contribution of edgeCount from all the pairs so far counted
29-
for(auto i: edgeCount){
30-
int u = i.first.first, v = i.first.second, w = i.second;
31-
// cout<<indegree[u] + indegree[v] - w<<endl;
32-
if(indegree[u] + indegree[v] > query && indegree[u] + indegree[v] - w <= query){
33-
total -= 1;
34-
}
35-
}
36-
ans.push_back(total);
4+
void update(int tind,int tl,int tr,int ind,int val){
5+
if(tl>tr)
6+
return;
7+
if(tl==tr){
8+
st[tind]+=val;
9+
return;
3710
}
38-
return ans;
11+
int tm=tl+((tr-tl)>>1),left=tind<<1;
12+
if(ind<=tm)
13+
update(left,tl,tm,ind,val);
14+
else
15+
update(left|1,tm+1,tr,ind,val);
16+
st[tind]=st[left]+st[left|1];
3917
}
40-
vector<int> countPairs(int n, vector<vector<int>>& edges, vector<int>& queries) {
41-
42-
vector<int>indegree(n, 0);
43-
for(auto edge: edges){
44-
int x = edge[0], y = edge[1];
45-
int u = min(x,y);
46-
int v = max(x,y);
47-
--u, --v;
48-
edgeCount[{u,v}] += 1;
49-
indegree[u]++;
50-
indegree[v]++;
18+
19+
int query(int tind,int tl,int tr,int ql,int qr){
20+
if(tl>tr or qr<tl or ql>tr)
21+
return 0;
22+
if(ql<=tl and tr<=qr)
23+
return st[tind];
24+
int tm=tl+((tr-tl)>>1),left=tind<<1;
25+
return query(left,tl,tm,ql,qr)+query(left|1,tm+1,tr,ql,qr);
26+
}
27+
28+
vector<int> countPairs(int n,vector<vector<int>>& a,vector<int>& q) {
29+
vector<int> f(n+2,0);
30+
vector<unordered_map<int,int>> mp(n+2); // using a normal map gives TLE
31+
32+
for(auto v:a){
33+
int mx=max(v[0],v[1]),mn=min(v[1],v[0]);
34+
f[mx]++;
35+
f[mn]++;
36+
mp[mx][mn]++;
5137
}
52-
53-
for(int i = 0; i < n; ++i){
54-
degree.push_back(indegree[i]);
38+
39+
vector<int> ans(q.size(),0);
40+
int m=a.size();
41+
st.resize(4*m+40,0);
42+
43+
for(int i=n;i;i--){
44+
// reducing the common edges between current node and its adjacent
45+
for(auto e:mp[i]){
46+
update(1,0,m,f[e.first],-1);
47+
update(1,0,m,f[e.first]-e.second,1);
48+
}
49+
50+
int curr=f[i];
51+
for(int j=0;j<q.size();j++)
52+
ans[j]+=query(1,0,m,max(0,q[j]-curr+1),m);
53+
54+
// reversing the changes made initially
55+
for(auto e:mp[i]){
56+
update(1,0,m,f[e.first],1);
57+
update(1,0,m,f[e.first]-e.second,-1);
58+
}
59+
60+
update(1,0,m,f[i],1);
5561
}
56-
sort(degree.begin(), degree.end()); // sort degree to apply smart two pointer
57-
return countPairsHelper(indegree, queries, n);
62+
return ans;
5863
}
5964
};

0 commit comments

Comments
 (0)