CCCC-GPLT L2-005. Set similarity double pointer

Posted by Shawazi on Sat, 04 Apr 2020 11:41:17 +0200

The similarity of two sets a and B is defined as n(A ∩ B)/n(A ∪ b). N () represents the size of the set
Given n(50) sets, each set gives a size M(1e4), followed by the number m (1e9)
k(2000) queries are given, and the similarity of two sets is queried each time

Before doing this problem, stl should know about it;
bool includes() determines whether a set is a subset of a set
Set Hou difference() returns the difference set of two sets
Set? Intersection() returns the intersection of two sets
Set? Symmetric? Difference() returns the set of symmetric differences between two sets
Set union() returns the union of two sets
All parameters are 4 iterator s

OK, this question has little to do with set
Theoretically, 2000*1e4 will time out, but it's too late to write a method to get intersection. pat evaluation is indeed 6 (maybe)
Note the value of de duplication

Two pointer scanning is used to obtain the intersection size. The union size can be obtained by the inclusion exclusion principle

/* LittleFall : Hello! */
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read();
inline void write(int x);
const int M = 100016;
vector<int> save[64];
int main(void)
{
#ifdef _LITTLEFALL_
    freopen("in.txt", "r", stdin);
#endif
    //std::cin.sync_with_stdio(false);

    int n = read();
    for(int i = 1; i <= n; i++)
    {
        int m = read();
        for(int j = 0; j < m; j++)
            save[i].push_back(read());
        sort(save[i].begin(), save[i].end());
        save[i].erase(unique(save[i].begin(), save[i].end()), save[i].end());
    }
    int k = read();
    while(k--)
    {
        int ta = read(), tb = read();
        int ln = 0, lu = save[ta].size() + save[tb].size(); //Union number
        for(int i = 0, j = 0;
                i < (int)save[ta].size() && j < (int)save[tb].size();
                i++, j++)
        {
            if(save[ta][i] < save[tb][j])
                j--; //i++
            else if(save[ta][i] > save[tb][j])
                i--; //j++
            else
                ln++;
        }
        printf("%.2f%%\n", 100.0 * ln / (lu-ln));
    }

    return 0;
}


inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void write(int x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}