Codeforces 547C/548E - Mike and Foam 题解

Codeforces 547C/548E - Mike and Foam 题解

Front cheese - inclusion and exclusion

Inclusion-exclusion principle isSimple Primary School Mathematical OlympiadSeeking multiple sets and sets of algorithms, the basic idea is probably the following:

This is a simple example: There \ (10 \) students like singing, there \ (15 \) students like dancing, there \ (5 \) students are like two activities, which did not like the two aforementioned activities student, then a total of how many students do?

I believe that smart you already know the answer, the answer is to be calculated by the following formula:
\ [10 + 15-5 = 20 (a) \]
right, is like elementary school Mathematical Olympiad. First of all like to sing or dance students together, after minus double counting \ (5 \) and all of the students like it.

Said formally (but here a set of three, to show more laws): \
[\ Vert A \ Cup B \ C Cup \ Vert = \ Vert A \ Vert + \ Vert B \ Vert + \ Vert C \ Vert - \ vert A \ cap B \
vert - \ vert A \ cap C \ vert - \ vert B \ cap C \ vert + \ vert A \ cap B \ cap C \ vert \] so, if there are more should the collection how you count it? In fact, it is not difficult (presentation may be unclear qaq):

Enumerate all subsets of the set up of a collection of (that is, 01 to enumerate each collection), if the current number of enumerated subset is odd, then add the intersection of their size, otherwise (that is, an even number), they subtracted the intersection of size.

He said formally (this should be clear): \
[\ Vert \ bigcup_. 1 = {I}} ^ {n-S_i \ Vert = \ sum_ {T \} the U-subseteq (-1) ^ {\ Vert T \ Vert - 1} \ vert \ bigcap_ {E \ in T} E \ vert \]

\ (S_i \) represents the \ (I \) th set and required to be set, \ (the U-\) represents all (S_i \) \ as a collection of elements, \ (T \) represents the current enumerated the \ (the U-\) subset, likewise, \ (T \) each element of a set, \ (\ Vert T \ Vert \) represents (T \) \ the number of the sets contained, \ (E \) represented as \ (S_i \) generally comprises a set of common elements.

The meaning of problems

Meaning of the questions is very simple, you \ (n \) beer, beer each several \ (a_i \) and \ (q \) operations, each query contains a number \ (the X-\) , represents the first \ ( x \) beer operations. If this cup of beer on the shelf, put it down, otherwise, we put up. After the output current on beer on the shelf, the logarithm of the number above prime to beer, formally speaking, is this:

Output \ ((i, j) \ ) number to when they satisfy \ (i <j \) and \ (\ GCD (a_i, a_j) =. 1 \) , \ (\ GCD \) represents the greatest common divisor.

The beer is called direct digital (number above it the subject of \ (a_i \) ) a.

The idea (mouth Hu)

To each number sequence is split into prime factors and the quality factor is required and set as a set, and can quickly calculate the current number of the counted number with a prime repellent and receiving data structures.

practice

First, we each number sequence is split into prime factors multiplied thereof, have the same quality factor will keep only one of them. Then, we'll maintain a data structure (recommended std::map, easy to use), save the prime factors are enumerated obtained by multiplying one of its factor (first key) to it as a factor (divided by its more than \ (0 \) number) \ (a_i \) number (second key) is. After the inclusion-exclusion method, it can be calculated the number of each of the current number is not prime with the number of its in the shelf, with the total number of click Save is the number of prime numbers. Adding and deleting number is also very convenient: When you add it took all factors (especially enumeration quality factor multiplied) in mapvalue in the plus one, minus one like it when deleted.

program

Feeling front approach is described in written procedures ah (I still really do not know too representation of it)

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int n,q,cnt;//cnt表示在架子上的啤酒的个数
ll tot;//tot是当前的所有的互质的数对的数量
int a[200005];
map<int,int> mp;//保存包含某个数作为因数的数a[i]的个数
vector<int> p[200005];//把数拆成质因子序列
bool onshelf[200005];//是否在架子上

void ext(int x,vector<int> &ps){
    if(x==1){//特判一就不拆了
        return;
    }
    for(int i=2;i*i<=x;i++){
        if(x%i==0){
            ps.push_back(i);
            while(x%i==0)x/=i;//去除重复的因子
        }
    }
    if(x>1)ps.push_back(x);//循环完可能还会有一个因子没有分解
}

void puton(int x){//添加第x个数到架子
    int res=cnt;//假设所有数都互质
    for(int s=1;s<(1<<p[x].size());s++){//枚举当前使用的质因数的集合
        int mt=1,bts=0;//mt为乘积,bts记录子集大小
        for(int i=0;i<p[x].size();i++){
            if(s&(1<<i)){
                mt*=p[x][i];
                bts++;
            }
        }//算出乘积
        if(bts&1){
            res-=mp[mt];
        }else{
            res+=mp[mt];
        }//容斥,正负相反是因为前面假设都是互质的
        mp[mt]++;//添加这个因子,由于枚举出的mt各不相同,所以不会重复计算
    }
    tot+=res;
}

void takeoff(int x){//拿走,基本同上
    int res=cnt;
    for(int s=1;s<(1<<p[x].size());s++){
        int mt=1,bts=0;
        for(int i=0;i<p[x].size();i++){
            if(s&(1<<i)){
                mt*=p[x][i];
                bts++;
            }
        }
        mp[mt]--;//先减去自己的那个因子,防止重复
        if(bts&1){
            res-=mp[mt];
        }else{
            res+=mp[mt];
        }
    }
    tot-=res;
}

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin>>n>>q;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        ext(a[i],p[i]);
    }
    while(q--){
        int x;cin>>x;
        if(onshelf[x]){
            cnt--;
            takeoff(x);
        }else{
            puton(x);
            cnt++;
        }
        onshelf[x]^=1;//作用就是取反
        cout<<tot<<endl;
    }

    return 0;
}

thank

Thank you for reading it! I was really very good number theory qaq, if there is anything unclear welcome message written below ~

Guess you like

Origin www.cnblogs.com/BlahDuckling747/p/12070489.html