hdu 多校联赛 TrickGCD
来源:互联网 发布:韩子高网络剧有下部吗 编辑:程序博客网 时间:2024/06/05 11:06
TrickGCD
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1218 Accepted Submission(s): 464
Problem Description
You are given an array A , and Zhu wants to know there are how many different array B satisfy the following conditions?
*1≤Bi≤Ai
* For each pair( l , r ) (1≤l≤r≤n ) , gcd(bl,bl+1...br)≥2
*
* For each pair( l , r ) (
Input
The first line is an integer T(1≤T≤10 ) describe the number of test cases.
Each test case begins with an integer number n describe the size of arrayA .
Then a line containsn numbers describe each element of A
You can assume that1≤n,Ai≤105
Each test case begins with an integer number n describe the size of array
Then a line contains
You can assume that
Output
For the k th test case , first output "Case #k: " , then output an integer as answer in a single line . because the answer may be large , so you are only need to output answer mod 109+7
Sample Input
144 4 4 4
Sample Output
Case #1: 17
Source
2017 Multi-University Training Contest - Team 2
思路:
找到
容斥的方法:莫比乌斯函数。
考虑一个数n,假设他能分解成三个质因数相乘:a*b*c,那么在算gcd为a、b、c时分别算了一遍,所以我们要减去gcd为a*b、a*c、b*c的,再加上gcd为a*b*c的。推广:我们需要加上质因数为奇数个的,减去质因数为偶数个的。当某个质因数的指数大于等于2,那么这个数我们之前肯定算过,所以这个不计入最后答案。
而莫比乌斯函数正好符合我们的需要(取个相反数就ok了)。
我们枚举gcd的时候已经花了n的时间了,所以接下来在算
我来解释一下这个式子:就是把枚举n个
#include <bits/stdc++.h>#define inf 0x3f3f3f3ftypedef long long int lli;using namespace std;const int mod = 1e9+7;const int maxn = 100200;bool isprime[maxn];//isprime数组用来标记素数和非素数 0代表是素数int prime[maxn],miu[maxn];void moblus()//通过莫比乌斯函数对范围内的数进行筛选 miu存的莫比乌斯函数的值{ int cnt = 0;//素数的个数 miu[1] = 1; for(lli i = 2; i < maxn; i++) { if(!isprime[i]) { prime[cnt++] = i; miu[i] = -1; } for(lli j = 0; j < cnt && i*prime[j] < maxn; j++) { isprime[i*prime[j]] = 1; if(i % prime[j]) miu[i*prime[j]] = -miu[i]; else { miu[i*prime[j]] = 0; break; } } }}inline lli qp(lli a,lli x)//快速幂求a的x次幂{ lli ans = 1; for(;x;x>>=1)//》=1属于位运算 相当于除2 { if(x&1) ans = ans*a%mod;//判断x的奇偶 a = a*a % mod; } return ans;}int a[102000],suma[202000];int main(){ int cas,t= 0,n,v,maxa,mina; scanf("%d",&cas);//输入测试样例的个数 moblus(); while(cas--) { t++; lli ans = 0;maxa = -100200,mina = 102000; scanf("%d",&n);//已知数组中元素的个数 memset(a,0,sizeof(a)); for(int i = 1;i <= n;i++) { scanf("%d",&v);//输入每组中的数 a[v]++;//a数组用来记这个数出现的个数 mina = min(mina,v);maxa = max(maxa,v);//找到每组数中的最小值和最大值 并标记 } for(int i = 1;i <= maxa*2;i++) { suma[i] = suma[i-1] + a[i];//将a数组进行累和 累出的和放在suma数组 } //这里进行了优化 因为动用了筛法 或者说对数据进行了分段 把算法的n^2变成了nlogn for(int i = 2;i <= mina;i++)//被除数x从2遍历到已知数组的最小值 { lli tempans = 1; for(int j = 1;j*i <= maxa;j++)//对j进行分段 以i的倍数进行分段 { tempans *= qp(j,(suma[i*j+i-1]-suma[i*j-1]));//分段的处理 间隔为suma数组的位数差i tempans %= mod; } ans -= miu[i]*tempans;ans %= mod;//根据容斥定理进行奇加偶减 } printf("Case #%d: %lld\n",t,(ans+mod)%mod);//这里ans先加mod是为了防止出现负数 }}
阅读全文
0 0
- hdu 多校联赛 TrickGCD
- HDU 6053 TrickGCD+6055 Regular polygon【2017多校联赛2】
- hdu 多校联赛 Questionnaire
- hdu 多校联赛 Classes
- hdu 多校联赛 Inversion
- TrickGCD HDU
- TrickGCD HDU
- 2017 杭电多校联赛第二场 1009 TrickGCD(容斥原理) HDU 6053
- 2015 HDU 多校联赛 5326 Work
- 2016多校联赛 hdu 5724 Chess
- 2016多校联赛 hdu 5728 PowMod
- HDU 5774 多校联赛第四场
- hdu 5823 2016多校联赛8
- hdu多校联赛 Balala Power!
- hdu 多校联赛 Regular polygon
- HDU 2017多校联赛-Regular polygon
- hdu 多校联赛 Maximum Sequence
- HDU 2017多校联赛-Maximum Sequence
- LeetCode 551 Student Attendance Record I
- python求解非递减排序的数组的一个旋转的最小元素
- POJ-3684 Physics Experiment(弹性碰撞)
- 问题 D: 天神下凡
- Puzzle HDU
- hdu 多校联赛 TrickGCD
- spring+springmvc+hibernate,实现分页功能
- hdu5692(dfs序+线段树 )Snacks
- 设计模式之禅笔记-命令模式
- 异常
- HDU 6053 TrickGCD 【容斥定理】【莫比乌斯函数】
- NOT IN和NOT EXISTS还有不一样的时候哦
- 选择开机自启动服务步骤---Linux系统
- 蝶恋花·伫倚危楼风细细