【1063 25 set】 Set Similarity

传送门

题意

给定 \(n\) 个集合,每个集合里面输入 \(m\) 个数 \(a_{i}\),给定 \(k\) 个查询,输入 \(l,r\) 根据集合 \(l,r\) 求出 \(N_{c}\) 即两个集合共有的数,\(N_{t}\) 两个集合合并后的不同的数,求出 \(N_{c}/N_{t}\),结果以百分号形式输出,并保留 \(1\) 位小数

数据范围

\(n\leq 50\)
\(m\leq 10^{4}\)
\(a_{i}\in [0,10^{9}]\)
\(k\leq 2000\)

题解

  • 用 set 自动去重特性存储
  • 每次查询初始化 \(N_{t}\) 为 set[r] 的数量
  • 遍历 set[l] 利用 find 函数查找当前值,如果 set[r] 中不存在那么nt++,存在的话即公共值 nc++
  • 因为 set 内部是有序的,find 基于二分每次查询为 \(O(nlogn)\)

Code

#include<bits/stdc++.h>
using namespace std;
#define in insert
#define sz size
map<int,bool>mp;
int main(){
    ios::sync_with_stdio(0); cin.tie(0);
    int n; cin>>n;
    set<int>s[n+1];
    for(int i=1;i<=n;i++){
        int m; cin>>m;
        for(int j=0;j<m;j++) { int x; cin>>x; s[i].in(x); }
    }
    int k; cin>>k;
    while(k--){
        int l,r; cin>>l>>r;
        int nc=0,nt=s[r].sz();
        for(auto it:s[l]) {
            if(s[r].find(it)==s[r].end()) nt++;
            else nc++;
        }
        double ans=(double)nc/nt*100;
        printf("%.1lf%%\n",ans);       
    }
}
posted @ 2021-02-27 01:05  Hyx'  阅读(42)  评论(0)    收藏  举报