欢迎来到就算过了一载春秋的博客

不管过了几载春秋,我还是会偶尔想起。

2019牛客暑期多校训练营(第一场) 补题

A.Equivalent Prefixes

题意:给定两个含n个元素的数组a,b,数组中不含相同元素,求最大的p(p<=n),使得a和b等价,这里等价的定义为a[l,r]和b[l,r]的最小值下标相等(1<=l<=r<=p)。

题解:

1、p的范围是1~n,从小到大遍历,利用单调栈求出La[i],表示第一个比a[i]小的元素的下标,Lb[i]同理。对第i个元素来说,如果Lu[i]!=Lv[i],说明包含i在内的区间不满足上述条件,那么p最大只能取i-1。

单调栈

AC代码:

 1 #include<iostream>
 2 #include<sstream>
 3 #include<fstream>
 4 #include<algorithm>
 5 #include<string>
 6 #include<cstring>
 7 #include<iomanip>
 8 #include<cstdlib>
 9 #include<cctype>
10 #include<vector>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ull unsigned long long
20 #define e 2.71828182
21 #define Pi acos(-1.0)
22 using namespace std;
23 const int MAXN=1e5+5;
24 int n,a[MAXN],b[MAXN];
25 int La[MAXN],Lb[MAXN]; 
26 stack<int> sa,sb;
27 int read()
28 {
29     int s=1,x=0;
30     char ch=getchar();
31     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
32     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
33     return x*s;
34 }
35 void init()
36 {
37     while(!sa.empty()) sa.pop();
38     while(!sb.empty()) sb.pop();
39     for(int i=1;i<=n;++i)
40     {
41         while(!sa.empty()&&a[i]<a[sa.top()]) sa.pop();
42         if(sa.empty()) La[i]=0;
43         else La[i]=sa.top();
44         sa.push(i);
45     }
46     for(int i=1;i<=n;++i)
47     {
48         while(!sb.empty()&&b[i]<b[sb.top()]) sb.pop();
49         if(sb.empty()) Lb[i]=0;
50         else Lb[i]=sb.top();
51         sb.push(i);
52     }
53 }
54 int main()
55 {
56     ios::sync_with_stdio(false);
57     cin.tie(0);cout.tie(0);
58     while(~scanf("%d",&n))
59     {
60         getchar();
61         for(int i=1;i<=n;++i) a[i]=read();
62         for(int i=1;i<=n;++i) b[i]=read();
63         int ans=n;
64         init();
65         for(int i=2;i<=n;++i)
66         {
67             if(La[i]!=Lb[i])
68             {
69                 ans=i-1;
70                 break;
71             } 
72         }
73         cout<<ans<<endl;
74     }
75 }
View Code

2、参考笛卡尔树做法

 

 B.Integration

题意:已知

给定n个不同的数a1,a2,...,an,求值:

结果可以被证明是一个有理数 p/q,输出模10e9+7的值

 题解:(这是让我回炉重造再学一遍高数吗???)参考裂项解方程+找规律

找到的规律是

 数论做的少,这里记一下:

若整数b,p互质,并且b | a,则存在一个整数x,使得

 

称x为b的模p乘法逆元,记为 b-1(mod p)

因为

所以

如果p是质数,并且b<p,根据费马小定理,bp-1≡1(mod p),即b*bp-2≡1(mod p)。因此,当模数p为质数时,bp-2即为b的乘法逆元。

如果只是保证b,p互质,那么乘法逆元可通过求解同余方程b*x≡1(mod p)得到。

有了乘法逆元,我们在计数问题中即使遇到a/b这样的除法算式,也可以先把a, b各自对模数p取模,再计算a*b-1 mod p作为最终的结果。当然,前提是必须保证b,p互质(当p时质数时,等价于b不是p的倍数)。

AC代码:

 1 #include<iostream>
 2 #include<sstream>
 3 #include<fstream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<iomanip>
 7 #include<cstdlib>
 8 #include<cctype>
 9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 using namespace std;
24 const int MOD=1e9+7;
25 const int MAXN=1e3+5;
26 ll qp(ll x,ll n)
27 {
28     ll ans=1;
29     while(n)
30     {
31         if(n&1) ans=ans*x%MOD;
32         x=x*x%MOD;
33         n>>=1;
34     }
35     return ans;
36 }
37 ll a[MAXN];
38 int n;
39 int read()
40 {
41     int s=1,x=0;
42     char ch=getchar();
43     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
44     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
45     return x*s;
46 }
47 int main()
48 {
49     ios::sync_with_stdio(false);
50     cin.tie(0);cout.tie(0);
51     while(~scanf("%d",&n))
52     {
53         for(int i=1;i<=n;++i) a[i]=read();
54         ll ans=0;
55         for(int i=1;i<=n;++i)
56         {
57             ll tmp=1;
58             for(int j=1;j<=n;++j)
59             {
60                 if(i==j) continue;
61                 tmp=tmp*((a[j]*a[j]%MOD-a[i]*a[i]%MOD+MOD)%MOD)%MOD;
62             }
63             tmp=tmp*2%MOD*a[i]%MOD;
64             ans=(ans+qp(tmp,MOD-2))%MOD;
65         }
66         cout<<ans<<endl;
67     }
68 }
View Code

 

C.Euclidean Distance

题意:给定n个数字a1到an,求n个实数p1到pn使得∑(ai/m-pi)2 最小,并且满足p1+p2+...+pn=1, p1,p2,...,pn>=0。输出最简分数。

题解:参考2019牛客暑期多校1C题 (数形结合好评)

ai是独立的,先排序,敢想,勇于贪心!也可以先想想n=2、3的情况,勇于贪心!

AC代码:

 1 #include<iostream>
 2 #include<sstream>
 3 #include<fstream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<iomanip>
 7 #include<cstdlib>
 8 #include<cctype>
 9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 using namespace std;
24 const int MAXN=1e4+5;
25 int read()
26 {
27     int s=1,x=0;
28     char ch=getchar();
29     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
30     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
31     return x*s;
32 }
33 int n,m;
34 ll a[MAXN];
35 void solve()
36 {
37     for(int i=1;i<=n;++i) a[i]=read();
38     sort(a+1,a+n+1,greater<int>());
39     int idx=n,res=m,tmp;
40     for(int i=1;i<n;++i)
41     {
42         if(i*(a[i]-a[i+1])<=res)
43         res-=i*(a[i]-a[i+1]);
44         else 
45         {
46             idx=i;break;
47         }
48     }
49     ll fz=(idx*a[idx]-res)*(idx*a[idx]-res);
50     for(int i=idx+1;i<=n;++i)
51     fz+=idx*a[i]*a[i];
52     ll fm=idx*m*m;
53     tmp=__gcd(fz,fm);
54     fz/=tmp,fm/=tmp;
55     if(!fz||fm==1) cout<<fz<<endl;
56     else cout<<fz<<'/'<<fm<<endl;
57 }
58 int main()
59 {
60     /*ios::sync_with_stdio(false);
61     cin.tie(0);cout.tie(0);*/
62     while(~scanf("%d%d",&n,&m))
63     {
64         solve();
65     }
66     return 0;
67 }
View Code

 

D.Parity of Tuples

题意:给定n 个m维向量,定义count(x)为满足条件的向量个数,满足的条件为:向量vi中的每一个数ai,j与x按位与后的二进制表示中要有奇数个1,1<=i<=n,1<=j<=m。

参考:2019多校第一场DParity of Tuples

告辞!

 

 E.ABBA

题意:

 构造一个长度为2*(m+n)的字符串,使得有一种子序列能拆分出n个AB及m个BA,求方案数。

题解:

2019牛客暑期多校训练(第一场)E-ABBA(卡特兰数的扩展)(超级无敌巨详细)

 

F.Random Point in Triangle

题意:给定三角形的三个点A(x1,y1),B(x2,y2),C(x3,y3),在三角形上找一点P,设E=max{SABP,SBCP,SACP},求E的期望

题解:参考:2019牛客暑期多校训练营(第一场)F.Random Point in Triangle(几何概型积分求期望)

答案是22倍三角形的面积

 1 import java.util.*;
 2 import java.io.*;
 3 public class Main {
 4  
 5     public static void main(String[] args) {
 6         Scanner cin=new Scanner(new BufferedInputStream(System.in));
 7         long x1,x2,x3,y1,y2,y3;
 8         while(cin.hasNext())
 9         {
10             x1=cin.nextLong();y1=cin.nextLong();
11             x2=cin.nextLong();y2=cin.nextLong();
12             x3=cin.nextLong();y3=cin.nextLong();
13             System.out.println(Math.abs(x2*y3+x1*y2+x3*y1-x1*y3-x3*y2-x2*y1)*11);
14         }
15          
16         cin.close();
17  
18     }
19  
20 }
View Code

 

G.Substrings 2

 

H.XOR

 

I.Points Division

 

J.Fraction Comparision

(签到题,略)

 

posted on 2019-07-23 18:57  就算过了一载春秋  阅读(264)  评论(0)    收藏  举报

导航