codeforces#305 547 C.C.Mike and Foam(モビウス反転)
1701 ワード
タイトルリンク:
クリックしてリンクを開く
テーマ:
1列の数を与えて、最初の集合は空で、それからq回の操作、毎回1つのxを与えて、もしx番目の数が存在するならば、削除して、追加が存在しないで、操作が終わった互質の数がどれだけ対があるかを聞きます
テーマ分析:
互質の数の対数を聞いて、裸の数の論題
まずf(k)はgcd(ai,aj)と定義する(1<=i
定義F(k)はk|gcd(ai,aj)(1<=i
では,モビウスの反転定理の第2の形式からf(k)=sigma(d>=1)[u(d)*F(d*k)]を得た.
cnt[i]をコレクション内のiの倍数の数として定義する数
F(k)=C(2,cnt[k])の結論は明らかである.
モビウスの反転を利用して、追加または削除する数に基づいて結果を修正し、出力すればいいのです
すなわち、与えられた数に対して素因数を分解し、現在の数がある素因数の2次方以上を含む場合、uは0に等しい
しかも2*3なので.....*17>500000なので、素因数の個数は6個を超えず、2^6種の影響を及ぼすF(k)を列挙すればよい
総複雑度q*2^6、絶対的な秒出
クリックしてリンクを開く
テーマ:
1列の数を与えて、最初の集合は空で、それからq回の操作、毎回1つのxを与えて、もしx番目の数が存在するならば、削除して、追加が存在しないで、操作が終わった互質の数がどれだけ対があるかを聞きます
テーマ分析:
互質の数の対数を聞いて、裸の数の論題
まずf(k)はgcd(ai,aj)と定義する(1<=i
定義F(k)はk|gcd(ai,aj)(1<=i
では,モビウスの反転定理の第2の形式からf(k)=sigma(d>=1)[u(d)*F(d*k)]を得た.
cnt[i]をコレクション内のiの倍数の数として定義する数
F(k)=C(2,cnt[k])の結論は明らかである.
モビウスの反転を利用して、追加または削除する数に基づいて結果を修正し、出力すればいいのです
すなわち、与えられた数に対して素因数を分解し、現在の数がある素因数の2次方以上を含む場合、uは0に等しい
しかも2*3なので.....*17>500000なので、素因数の個数は6個を超えず、2^6種の影響を及ぼすF(k)を列挙すればよい
総複雑度q*2^6、絶対的な秒出
#include
#include
#include
#include
#include
#define MAX 500007
using namespace std;
typedef long long LL;
int n,q,x;
int a[MAX];
int u[MAX];
int used[MAX];
int cnt[MAX];
int maxPrime[MAX];
vector v;
LL ans;
void init ( )
{
memset ( maxPrime , -1 , sizeof ( maxPrime ) );
for ( int i = 1 ; i < MAX ; i++ ) u[i] = 1;
for ( int i = 2 ; i < MAX ; i++ )
{
if ( ~maxPrime[i] ) continue;
for ( int j = 1 , t = i ; t < MAX ; j++,t += i )
{
maxPrime[t] = i;
u[t] = j%i==0?0:-u[t];
}
}
}
void update ( int x , int f )
{
v.clear();
while ( x > 1 )
{
int p = maxPrime[x];
v.push_back(p);
while ( x%p == 0 )
x /= p;
}
int m = v.size();
int total = 1<