输入n和a,求满足 an+bn=cn 的b和c
由费马大定理知当n>2时,不存在正整数a,b,c满足上式。
当n==1时,直接随便找两个数就行了
当n==2时,就变成了勾股定理。我们发现当a为奇数(c-b)==1,当a为偶数(c-b)==2。
则我们可以得到结论:a为奇数,b=(a2-1)/2,c=(a2+1)/2;a为偶数,b=(a2/2-2)/2,c=(a2/2+2)/2。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 6 int main() 7 { 8 int t,n,a; 9 scanf("%d",&t); 10 while(t--) 11 { 12 scanf("%d %d",&n,&a); 13 if(n==0) 14 printf("-1 -1 "); 15 if(n==1) 16 printf("1 %d ",a+1); 17 if(n==2) 18 { 19 if(a%2==0) 20 printf("%d %d ",(a*a/2-2)/2,(a*a/2+2)/2); 21 else 22 printf("%d %d ",(a*a-1)/2,(a*a+1)/2); 23 } 24 if(n>=3) 25 printf("-1 -1 "); 26 } 27 return 0; 28 }
建树,以每一条边把树分成两个子树,假设其中一棵子树的节点数为m,另一个就为(n-m),那么这条边出现的次数就为m*(n-m)*2,算出每条边的贡献值m*(n-m)*2*(n-1)!*w,再求他们的和就行了。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 const int N=1e5+5; 6 const int mod=1e9+7; 7 struct Edge 8 { 9 int to,next,w; 10 }edge[N*2]; 11 int head[N],tot; 12 ll ans,fac; 13 int n; 14 void init() 15 { 16 tot=0; 17 memset(head,-1,sizeof(head)); 18 fac=1; 19 for(int i=1;i<=n-1;i++) 20 fac=fac*i%mod; 21 } 22 void addEdge(int u,int v,int w) 23 { 24 edge[tot].to=v; 25 edge[tot].next=head[u]; 26 edge[tot].w=w; 27 head[u]=tot++; 28 } 29 30 int dfs(int u,int pre) 31 { 32 int Size=1; 33 for(int i=head[u];i!=-1;i=edge[i].next) 34 { 35 int v=edge[i].to; 36 if(v==pre) continue; 37 int sz=dfs(v,u); 38 ll tmp=(ll)(n-sz)*sz%mod*2%mod*fac%mod*edge[i].w%mod; 39 ans=(ans+tmp)%mod; 40 Size+=sz; 41 } 42 return Size; 43 } 44 int main() 45 { 46 while(scanf("%d",&n)!=EOF) 47 { 48 int u,v,w; 49 init(); 50 for(int i=1;i<=n-1;i++) 51 { 52 scanf("%d%d%d",&u,&v,&w); 53 addEdge(u,v,w); 54 addEdge(v,u,w); 55 } 56 ans=0; 57 dfs(1,-1); 58 printf("%lld ",ans); 59 } 60 // cout << "Hello world!" << endl; 61 return 0; 62 }