1005:Euler theorem
题意:给一个数a,求(a%x)的值有多少种。
分析:对于大于a/2的数,设为t,那么a%t =(a- t).对于小于等于a/2的数t,必然存在一个整数z,使得 z*ta,z*t>a,此时答案就是 a-z*t.(前面已出现的答案)。
对于大于a的数,a%t = a。所以答案就呼之欲出了。
#include
#include
#include
#include
#include
#include
#define siz 100005
#define LL long long
using namespace std;
int n,m;
int euler(int n){
int res=n,a=n;
for(int i=2;i*i<=a;i++){
if(n%i==0){
res=res/i*(i-1);
while(n%i==0) n/=i;
}
}
if(n>1) res=res/n*(n-1);
return res;
}
int main()
{
int t,a;
scanf("%d",&t);
while(t--)
{
scanf("%d",&a);
printf("%d\n",(a+1)/2+1);
}
return 0;
}
题意:给一组数,让你求第n的数。
规律:
#include
#include
#include
#include
#include
#include
#define siz 10000100
#define LL long long
using namespace std;
int gp[siz];
int x[siz];
void solve(){
gp[1] = 1;
gp[2] = 2;
//gp[3] = 2;
x[1] = 1;
int i = 2;
int j = 2;
int flag = 2;
while(j
1008:题意:给n个坐标点,以及这个点的价值v,定义两个点之间的价值是vi*vj。现让你画一条过原点的的直线,将平面上的点分成两部分,然后将两部分之间 的两两之间求价值,使得价值最大。
分析:对于平面上所有的点,必然会存在一条直线将他们分成两部分,所以我们可以枚举分成的这些两部分。维护一个最大值。
然后,那条线必然是穿过1,3象限或者2,4象限。我们可以将每个点与原点连线,求得一个斜率,然后按照斜率从小到大排序,开始的那条直线可以先平行于x轴开始,再平行于y轴开始,旋转,每次旋转一个当前两个象限斜率小的那个点,而对于答案,对于条直线分成的两部分,设价值和分别为sum1和sum2,那么答案自然是sum1*sum2.而当我们旋转过一个点时,设转 过斜率的价值和为v(在那个斜率的直线上可能有很多点),那么价值为 (sum2 - v) *(sum1+v).暴力分两次更新就行。
#include
#include
#include
#include
#define siz 105
const int maxn = 50000;
const double infk = 2000000000;
typedef long long LL;
using namespace std;
struct node
{
int x,y,w;
double k;
} G[5][maxn+5];
/*
5
8
2 2 2
1 1 2
3 0 100
1 -2 10
-1 1 5
-1 0 5
-1 -1 10
-1 3 10
*/
int n,tot[5];
LL ans;
int isg(int x,int y)
{
if(x>=0&&y>=0) return 1;
if(x<0&&y>=0) return 2;
if(x<0&&y<0) return 3;
if(x>=0&&y<0) return 4;
return 0;
}
double fk(int x,int y)
{
if(x) return y*1.0/x*1.0;
return infk*1.0;
}
bool cmp(node A,node B)
{
return A.k < B.k;
}
void finmin(int &s1,int &s2,LL&cot1,LL&cot2,int g1,int g2)
{
int i;
G[g1][tot[g1]+1].k = infk+105;
G[g2][tot[g2]+1].k = infk+105;
if(G[g1][s1+1].k*1.0G[g2][s2+1].k)
{
for(i=s2+1;G[g2][i].k==G[g2][s2+1].k; i++) cot2+=G[g2][i].w;
s2=i-1;
}
else
{
for(i=s1+1; G[g1][i].k==G[g1][s1+1].k; i++) cot1+=G[g1][i].w;
s1=i-1;
for(i=s2+1; G[g2][i].k==G[g2][s2+1].k; i++) cot2+=G[g2][i].w;
s2=i-1;
}
}
}
void ok(int g1,int g2,LL sum1,LL sum2)
{
LL cot1,cot2;
int s1=0,s2=0;
while(s1