Hdu 6134 Battlestation Operational【容斥】

来源:互联网 发布:文豆php培训学校 编辑:程序博客网 时间:2024/05/21 21:33

Battlestation Operational

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 280    Accepted Submission(s): 151


Problem Description
> The Death Star, known officially as the DS-1 Orbital Battle Station, also known as the Death Star I, the First Death Star, Project Stardust internally, and simply the Ultimate Weapon in early development stages, was a moon-sized, deep-space mobile battle station constructed by the Galactic Empire. Designed to fire a single planet-destroying superlaser powered by massive kyber crystals, it was the pet project of the Emperor, Darth Vader, and its eventual commander Grand Moff Wilhuff Tarkin to expound the military philosophy of the aptly named Tarkin Doctrine.
>
> — Wookieepedia

In the story of the Rogue One, the rebels risked their lives stolen the construction plan of the Death Star before it can cause catastrophic damage to the rebel base. According to the documents, the main weapon of the Death Star, the Superlaser, emits asymmetric energy in the battlefield that cause photons to annihilate and burns everything in a single shot.

You are assigned the task to estimate the damage of one shot of the Superlaser. 

Assuming that the battlefield is an n×n grid. The energy field ignited by the Superlaser is asymmetric over the grid. For the cell at i-th row and j-th column, i/junits of damage will be caused. Furthermore, due to the quantum effects, the energies in a cell cancel out if gcd(i,j)1 or i<j.

The figure below illustrates the damage caused to each cell for n=100. A cell in black indicates that this cell will not be damaged due to the quantum effects. Otherwise, different colors denote different units of damages.

Your should calculate the total damage to the battlefield. Formally, you should compute
f(n)=i=1nj=1iij[(i,j)=1],


where [(i,j)=1] evaluates to be 1 if gcd(i,j)=1, otherwise 0.
 

Input
There are multiple test cases.

Each line of the input, there is an integer n (1n106), as described in the problem. 

There are up to 104 test cases.
 

Output
For each test case, output one integer in one line denoting the total damage of the Superlaser, f(n) mod 109+7.
 

Sample Input
1 2310
 

Sample Output
138110

题目大意:


F(n)=ΣΣi/j(gcd(i,j)==1);

让你求F(n)的值。


思路(思路代码参考自:http://blog.csdn.net/jaihk662/article/details/77338339):


我们设定g【i】表示每一行对结果贡献的价值。


那么我们不妨列出特殊的几列的值进行探讨:

现在列出所有位子的价值:

 12345611/1     22/12/2    33/13/23/3   44/14/24/34/4  55/15/25/35/45/5 66/16/26/36/46/56/6

其结果(上边是所有位子的价值,下边是每个位子真实贡献的价值):



我们假设要计算第六行的价值,我们需要去掉GCD(6,i)>1的所有位子的价值。


①第6行的贡献有:6/1,6/2,6/3,6/4,6/5,6/6

②第3行的贡献有:3/1,3/2,3/3.

③第2行的贡献有:2/1,2/2.

④第1行的贡献有:1/1.

我们将各式化简,有:

①第6行的贡献有:6/1,3/1,2/1,3/2,6/5,1/1

②第3行的贡献有:3/1,3/2,1/1.

③第2行的贡献有:2/1,1/1.

④第1行的贡献有:1/1.


然后我们考虑将各式子中1/1的部分去掉(因为gcd(i,i)一定大于1)有:

①第6行的贡献有:2 3 4 6,即:6/1,3/1,2/1,3/2,6/5

②第3行的贡献有:1 3.即:3/1,3/2

③第2行的贡献有:1 2.即:2/1


显然我们如果要计算第六行的实际贡献的话,需要将Gcd(6,i)>1的部分都去掉,那么显然要去掉的值有:3/1,2/1,3/2.

那么我们不难发现,此时我们对于第六行的实际贡献,只要将第二行和第三行的实际贡献去掉即可。


整个过程很容易理解,那么我们容斥一下就行。


设定G【i】表示我们第i行的全部贡献,设定F【i】表示我们第i行的实际贡献,那么就有:F【i】-=F【j】(j是i的因子)

容斥过程我们O(nlogn)就能够实现。


那么考虑如何计算G【i】,打表发现,我们每一行的全部贡献值是可以递推出来的,G【i】=G【i-1】+d【i-1】+1;

这里d【i】表示数字i因子数的个数。


那么预处理一下d【i】,再递推得到G【i】,然后容斥一下得到F【i】即可。


Ac代码:

#include<stdio.h>#include<string.h>using namespace std;#define ll __int64#define maxn 1000050#define mod 1000000007ll d[1050000];ll g[1050000];ll f[1050000];int main(){    for(int i=1;i<=maxn;i++)    {        for(int j=i;j<=maxn;j+=i)        {            d[j]++;        }    }    for(int i=1;i<=maxn;i++)    {        g[i]=g[i-1]+d[i-1]+1;        g[i]%=mod;    }    for(int i=1;i<=maxn;i++)    {        for(int j=i*2;j<=maxn;j+=i)        {            g[j]-=g[i];            g[j]=(g[j]%mod+mod)%mod;        }    }    for(int i=1;i<=maxn;i++)    {        f[i]=f[i-1]+g[i];        f[i]=(f[i]%mod+mod)%mod;    }    ll n;    while(~scanf("%I64d",&n))    {        printf("%I64d\n",f[n]);    }}









阅读全文
0 0