ECJTU16级校赛
第四题:
LB的公式
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 40 Accepted Submission(s) : 16
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
LB是个十分喜欢钻研的人,对什么事都要搞明白。 有一天他看到一个公式,((a-b)*c+d*e)/f=k。他想如果给定K的值, 一共有多少种不同整数的组合(a,b,c,d,e,f)使公式成立,(-50≤a,b,c,d,e,f≤50)LB算了很久都没有算出来, 所以他向你求助,由于答案很大,所以对1e9+7取模
Input
第一行只包含一个整数T(T≤100),表示测试用例的个数。 对于每个测试用例,第一行只包含一个整数K(-500≤K≤500)
Output
对于每个测试用例,输出最后对1e9+7取模的答案。
Sample Input
1 500
Sample Output
27194104 移项,得(a-b)*c=k*f-d*e,易得公式左边取值范围为[-5000,5000],暴力求解出公式左右两边值为N的不同个数x,然后分别对应相乘,再求和、取模,时间复杂度为o(n^3),n为50,注意f不能为0。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<vector> 6 #include<set> 7 #include<map> 8 #define ll long long 9 using namespace std; 10 const ll eps=1e9+7; 11 const int mod=eps; 12 const int N=1e5+5; 13 // map<int,int>mp1; 14 //map<int,int>mp2; 15 int main() 16 { 17 int t,k,b,a,c,d,e,f,mp1[60001],mp2[60001];ll ans; 18 scanf("%d",&t); 19 while(t--) 20 { 21 ans=0; 22 memset(mp1,0,sizeof(mp1)); 23 memset(mp2,0,sizeof(mp2)); 24 scanf("%d",&k); 25 for(a=-50;a<=50;a++) 26 for(b=-50;b<=50;b++) 27 for(c=-50;c<=50;c++) 28 { 29 mp1[(a-b)*c+27500]++; 30 } 31 for(f=-50;f<=50;f++) 32 for(d=-50;d<=50;d++) 33 for(e=-50;e<=50;e++) 34 { 35 if(f!=0)mp2[(k*f-d*e)+27500]++; 36 } 37 for(int i=0;i<60000;i++) 38 { 39 ans+=mp1[i]*mp2[i];//printf("%d %d\n",mp1[i],mp2[i]); 40 } 41 //printf("%lld\n",ans); 42 printf("%lld\n",ans%mod); 43 } 44 return 0; 45 }
第一个式子的范围为(-5000,5000),第二个式子 的范围为(-27500,27500)
所以数组下标+27500;
一开始用了map超时,因为不会将map清0,所以每次都新创建了map应该是这里的原因
第五题:
最近侯ry感觉自己在数学方面的造诣不忍直视;他发现他的学习速率呈一个指数函数递增,疯狂的陷入学习的泥潭,无法自拔;他的队友发现了他的学习速率y=e^(b*lna+lnc); e是科学界非常重要而常见的常数,e=2.718281828……。 侯ry由于数学很差不会算学习数率y,现求助于学弟,感激不尽;
Input
多组数据,每组数据输入三个整数a,b,c(a,c<=10^12,b<=10^100000)
Output
一个整数y,对10^9+7取模
Sample Input
2 3 10
Sample Output
80 欧拉定理:对于互质的正整数a和n,有a^phi(n)≡1 mod n,题目求a^b*c%mod;把b%(mod-1)即可快速幂一下。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define ll long long 6 const ll eps=1e9+7; 7 const int mod=eps; 8 using namespace std; 9 int main() 10 { 11 ll a,b,c,pinb,i,j,k,l,ans;char bstr[100005]; 12 while(~scanf("%lld",&a)) 13 { 14 scanf("%s%lld",bstr,&c); 15 l=strlen(bstr);k=0;ans=1;b=0; 16 for(i=0;i<l;i++) 17 { 18 b=b*10+(bstr[i]-'0'); 19 if(b>=mod-1)b%=mod-1,k=1; 20 } 21 //cout<<mod-1<<endl; 22 if(k==1)b+=mod-1; 23 a%=mod; 24 while(b>0) 25 { 26 if(b&1)ans=(ans*a)%mod; 27 a=(a*a)%mod; 28 b>>=1; 29 } 30 printf("%lld\n",ans*(c%mod)%mod); 31 } 32 return 0; 33 }
质数n的欧拉数为n-1,欧拉数的定义为:小于等于n的数中有多少个和他互质的数,质数除了不与自己互质,1~n-1都互质
以下是百度的类似的模板
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define ll long long 6 const ll eps=1e9+7; 7 const int mod=eps; 8 using namespace std; 9 /*ll powmod(ll a,ll n) 10 { 11 ll ans=1; 12 a%=mod; 13 while(n>0) 14 { 15 if(n&1)ans=(ans*a)%mod; 16 n/=2; 17 a=(a*a)%mod; 18 } 19 return ans; 20 } 21 int main() 22 { 23 ll a,b,c; 24 while(~scanf("%lld%lld%lld",&a,&b,&c)) 25 { 26 c%=mod; 27 //printf("%d\n",powmod(a,b)); 28 ll ans=(powmod(a,b)*c)%mod; 29 printf("%lld\n",ans); 30 } 31 return 0; 32 }*/ 33 const __int64 c=1e9+7; 34 char b[1000005]; 35 __int64 phi(__int64 a) //求欧拉函数值 36 { 37 __int64 ans=a; 38 for(int i=2;i*i<=a;i++) 39 { 40 if(a%i==0) 41 { 42 ans=ans/i*(i-1); 43 while(a%i==0) a/=i; 44 } 45 } 46 if(a>1) ans=ans/a*(a-1); 47 return ans; 48 } 49 int main() 50 { 51 __int64 a,t,d,phic,newb,len,i; 52 while(~scanf("%I64d",&a)) 53 { 54 bool flag=false; //b是否大于phic 55 scanf("%s%I64d",b,&d); 56 a%=c,t=1,phic=phi(c),len=strlen(b),newb=0; 57 for(i=0;i<len;i++) //求b%phi(c) 58 { 59 newb=newb*10+(b[i]-'0'); 60 if(newb>=phic) newb%=phic,flag=true; 61 } 62 if(flag==true) newb+=phic; //新的指数为b%phi(c)+phi(c) 63 while(newb-1) 64 { 65 if(newb&1) t=t*a%c; 66 newb>>=1,a=a*a%c; 67 } 68 printf("%I64d\n",(a*t%c)*(d%c)%c); 69 } 70 return 0; 71 }
第七题:
acm小学妹
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 49 Accepted Submission(s) : 19
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
ACM小学妹在今天的暑假训练结束后,想看球赛放松一下。当他打开电脑时查询到联盟今天直播N场球赛,每场球赛的起止时间(S1,E1),(S2,E2),...,(SN,EN)。现在小学妹想今天看完所有的球赛直播,不至于留到明天看重播了,毕竟明天依旧是要训练的。当小学妹看完这场球赛要切换到其他球赛时是不需要时间的。现在小学妹用自己训练用的电脑来看球赛,但是可能不够。毕竟小学妹自己的电脑最多只能同时播放1场直播,现在小学妹需要借一些电脑来同时播放球赛。本来小学妹自己是可以求出最少需要借多少台电脑来同时观看的,但是今天训练太累了,你可以帮助他吗?
Input
包含多组输入,第一行输入一个整数N(1≤N≤100000),表示任务的数目。以下N行每行两个整数Si,Ei,(0≤Si<Ei≤1000000000),表示任务的起至时间。
Output
输出小学妹最少需要借的电脑数目。
Sample Input
5 1 10 2 7 6 9 3 4 7 10
Sample Output
2 题解:
.每场球赛的起始时间s:x=s,y=1;每场球赛的终止时间e:x=e,y=-1,按x非递减排序,x相同按y非递减排序。输出y的前缀和的最大值。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define ll long long 6 const ll eps=1e9+7; 7 const int mod=eps; 8 const int N=1e5+5; 9 struct TV 10 { 11 ll time; 12 int ps; 13 bool operator < (TV a)const{ 14 if(a.time==time) 15 return a.ps>ps; 16 else 17 return a.time>time; 18 } 19 }tv[N]; 20 using namespace std; 21 int main() 22 { 23 ll i,j,n;int f[2*N],ans; 24 while(~scanf("%lld",&n)) 25 { 26 memset(f,0,sizeof(f)); 27 for(i=0;i<2*n;i+=2) 28 { 29 scanf("%lld%lld",&tv[i].time,&tv[i+1].time); 30 tv[i].ps=1;tv[i+1].ps=-1; 31 } 32 ans=0;f[0]=tv[0].ps; 33 sort(tv,tv+2*n); 34 for(i=1;i<2*n;i++) 35 { 36 f[i]=f[i-1]+tv[i].ps; 37 ans=max(f[i],ans); 38 } 39 /*for(i=0;i<2*n;i++) 40 { 41 printf("%d ",tv[i].ps); 42 } 43 printf("\n"); 44 for(i=0;i<2*n;i++) 45 { 46 printf("%lld ",tv[i].time); 47 } 48 printf("\n"); 49 for(i=0;i<2*n;i++) 50 { 51 printf("%d ",f[i]); 52 } 53 printf("\n");*/ 54 if(ans>0) 55 printf("%d\n",ans-1); 56 else 57 printf("0\n"); 58 } 59 return 0; 60 } 61 /* 62 5 63 1 10 64 2 7 65 5 10 66 3 6 67 7 10 68 */
第八题:
毛线数列最值
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 43 Accepted Submission(s) : 15
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
halfyarn找你写个简单的题?好哒!给你n个整数,现在要求你选择两个位置的数,例如选择第pos_a个数a,和第pos_b个数b,给定ans=min(a,b)*abs(pos_a-pos_b),输出ans的最大值。
Input
第一行输入一个n代表有n个数,接下来的一行输入n个整数; 2<=n<=1e6; 1<=a,b<=1e6; 注意多组输入;
Output
ans的最大值;
Sample Input
4 1 2 2 2
Sample Output
4 O(n)处理,注意开LL,取数列的左右界l,r,得到初始答案ans,每次取min(a[l],a[r])的一侧向中心遍历,当找到更大的数时,能更新则更新答案,当l>r结束,输出ans。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define ll long long 6 const ll eps=1e9+7; 7 const int mod=eps; 8 const int N=1e6+5; 9 ll a[N]; 10 using namespace std; 11 int main() 12 { 13 ll r,l,i,j,n,ans; 14 while(~scanf("%lld",&n)) 15 { 16 ans=0; 17 for(i=0;i<n;i++) 18 scanf("%lld",&a[i]); 19 r=0;l=n-1; 20 while(l>r) 21 { 22 ans=max(ans,min(a[r],a[l])*(l-r)); 23 if(a[r]==min(a[r],a[l])) 24 r++; 25 else l--; 26 } 27 printf("%lld\n",ans); 28 } 29 return 0; 30 }