您的位置:首页 > 其它

周中训练笔记+Uva10616+10820

2017-11-09 21:46 483 查看
前天晚上看到有人一发a了那个大家都wa的欧拉函数的题,半夜十一点多就有人在群里问为什么,竟然是phi[1]=0,并且有人说本来不就应该是0吗,我一直以为是1,我很迷,百度百科了一下,确实是1啊,在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1)。欧拉函数百度百科,可能确实是judge的不同

只选了两个题目,放个欧拉函数相关的,见题目详解

When participating in programming contests, you sometimes face the following problem: You knowhow to calcutale the output for the given input values, but your algorithm is way too slow to everpass the
time limit. However hard you try, you just can’t discover the proper break-off conditions thatwould bring down the number of iterations to within acceptable limits.

Now if the range of input values is not too big, there is a way out of this. Let your PC rattle for halfan hour and produce a table of answers for all possible input values, encode this table into a
program,submit it to the judge, et voila: Accepted in 0.000 seconds! (Some would argue that this is cheating,but remember: In love and programming contests everything is permitted).

Faced with this problem during one programming contest, Jimmy decided to apply such a ’technique’.But however hard he tried, he wasn’t able to squeeze all his pre-calculated values into a programsmall
enough to pass the judge. The situation looked hopeless, until he discovered the following propertyregarding the answers: the answers where calculated from two integers, but whenever the twoinput values had a common factor, the answer could be easily derived
from the answer for which theinput values were divided by that factor. To put it in other words:

Say Jimmy had to calculate a function Answer(x, y) where x and y are both integers in the range[1, N]. When he knows Answer(x, y), he can easily derive Answer(k ∗ x, k ∗ y), where k is any integerfrom
it by applying some simple calculations involving Answer(x, y) and k.

For example if N = 4, he only needs to know the answers for 11 out of the 16 possible input valuecombinations: Answer(1, 1), Answer(1, 2), Answer(2, 1), Answer(1, 3), Answer(2, 3), Answer(3, 2),Answer(3,
1), Answer(1, 4), Answer(3, 4), Answer(4, 3) and Answer(4, 1). The other 5 can be derivedfrom them (Answer(2, 2), Answer(3, 3) and Answer(4, 4) from Answer(1, 1), Answer(2, 4) fromAnswer(1, 2), and Answer(4, 2) from Answer(2, 1)). Note that the function Answer
is not symmetric,so Answer(3, 2) can not be derived from Answer(2, 3).

Now what we want you to do is: for any values of N from 1 upto and including 50000, give thenumber of function Jimmy has to pre-calculate.

Input

The input file contains at most 600 lines of inputs. Each line contains an integer less than 50001 whichindicates the value of N. Input is terminated by a line which contains a zero. This line should
not beprocessed.

Output

For each line of input produce one line of outpu
c330
t. This line contains an integer which indicates howmany values Jimmy has to pre-calculate for a certain value of N.

Sample Input

2

5

0

Sample Output

3

19

题意:问你1~n之间有多少对数互质

思路:很明显的欧拉函数

已经说明(1,2)(2,1)算是两组,这样就会出现出去1之外的数互质的个数等于phi[i]*2

加上最初的(1,1)即可

换个说法就是把所有小鱼n的全乎乘以2之后,减去(1,1)(1,1)这组重复的即可

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
using namespace std;
#define ll long long
#define N 100010
int phi
;
int prime
;
void Euler()
{
prime[0]=prime[1]=0;
memset(prime,-1,sizeof(prime));
for(int i=2;i*i<=N;i++)
{
if(prime[i])
{
for(int j=i*i;j<=N;j+=i)
prime[j]=0;
}
}
for(int i=1;i<=N;i++)
phi[i]=i;
for(int i=2;i<=N;i++)
{
if(prime[i])
{
for(int j=i;j<=N;j+=i)
phi[j]=phi[j]/i*(i-1);
}
}
}
int main()
{
Euler();
//for(int i=1;i<20;i++)
//cout<<phi[i]<<endl;
int n;
while(cin>>n)
{
if(n==0)
break;
ll ans=0;
for(int i=2;i<=n;i++)
ans+=(phi[i]*2);
ans++;
cout<<ans<<endl;
}
return 0;
}Given a list of N numbers you will be allowed to choose any M of them. So you can choose in (NM)ways. You will have to determine how many of these chosen groups have a sum, which
is divisible byD.
Input

The input file contains maximum ten sets of inputs.

 The description of each set is given below.The first line of each set contains two integers N (0 < N ≤ 200) and Q (0 < Q ≤ 10). Here Nindicates how many numbers are there and Q is the total no of query.
Each of the next N lines containsone 32 bit signed integer. Our queries will have to be answered based on these N numbers. Next Qlines contain Q queries. Each query contains two integers D (0 < D ≤ 20) and M (0 < M ≤ 10) whosemeanings are explained in the
first paragraph.

Input is terminated by a case whose N = 0 and Q = 0. This case should not be processed.

Output

For each set of input, print the set number. Then for each query in the set print the query numberfollowed by the number of desired groups. See sample output to know the exact output format.

Sample Input

10 2



2

3

4

5

6

7

8

9

10

5 1

5 2

5 1

2

3

4

5

6

5 1

0 0

Sample Output

SET 1:

QUERY 1: 2

QUERY 2: 9

SET 2:

QUERY 1: 1

题意:给出n个数,q组查询,每次查询给出mod,和m,问你从这n个数里选出m个数的和整除mon等于0的选法个数

思路:200的20,感觉不是挺大,dfs时做过全排列的问题,果断写个搜索,tle好几发,找了好几种排列的方法,也是超时,无奈网上借来他人智慧,竟然是dp。

ans[i][j]代表i个数组成的值为j的个数

/*...........*/是部分dfs代码

import java.util.Scanner;

public class Main {

static int N=210;
static int [] map=new int[100010];
static int [][] ans=new int [110][N*N];
static int [] map2=new int[100000];
static int n;
static int m;
static int mod;
public static long solve(long sum)
{
for(int i=0;i<110;i++)
for(int j=0;j<N*N;j++)
ans[i][j]=0;
long temp=0;
ans[0][0]=1;
for(int i=0;i<n;i++)
{
for(int j=m-1;j>=0;j--)
{
for(int k=0;k<=sum;k++)
ans[j+1][k+map2[i]]+=ans[j][k];
}
}
for(int i=0;i<=sum;i+=mod)
temp+=ans[m][i];
return temp;
}
/*public static void dfs(int k)
{
for(int i=1;i<=n;i++)
{
if(vis[i]==0)
{
a[k]=b[i];
vis[i]=1;
if(k==m)
{
long temp=0;
for(int j=1;j<=m;j++)
{
//System.out.print(a[j]+" ");
temp+=a[j];
}
if(temp%mod==0)
{
ans++;
//System.out.println(temp);
}
//System.out.println();
}
else dfs(k+1);
vis[i]=0;
}
}
}*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin=new Scanner (System.in);
int cas=1;
while(cin.hasNext())
{
n=cin.nextInt();
int gg=cin.nextInt();
if(n==0&&gg==0)
break;
for(int i=0;i<n;i++)
map[i]=cin.nextInt();
System.out.print("SET "+cas+":\n");
cas++;
for(int i=1;i<=gg;i++)
{
mod=cin.nextInt();
m=cin.nextInt();
long sum=0;
for(int j=0;j<n;j++)
{
map2[j]=(map[j]%mod+mod)%mod;
sum+=map2[j];
//System.out.print(map2[j]+" ");
}
System.out.println("QUERY "+i+": "+solve(sum));
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: