一套模拟赛

昨晚的模拟赛很好啊

T1:Super GCD

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 struct bignum{
 8     int a[205],len;
 9     bignum(){
10         memset(a,0,sizeof a);
11         len=0;
12     }
13     bignum(int x){
14         memset(a,0,sizeof a);len=0;
15         while(x){
16             a[++len]=x%10;
17             x/=10;
18         }
19     }
20     void div(){
21         for(int i=len;i;i--){
22             if((i>1)&&(a[i]&1))a[i-1]+=10;
23             a[i]>>=1;
24         }
25         while(len>1&&!a[len])len--;
26     }
27     bignum operator - (bignum b){
28         bignum c;
29         c.len=max(len,b.len);
30         for(int i=1;i<=c.len;i++){
31             c.a[i]+=a[i]-b.a[i];
32             if(c.a[i]<0){
33                 c.a[i]+=10;
34                 a[i+1]--;
35             }
36         }
37         while(c.a[c.len+1])c.len++;
38         while(c.len>1&&!c.a[c.len])c.len--;
39         return c;
40     }
41     bool operator < (const bignum & b)const{
42         if(b.len>len)return 1;
43         for(int i=len;i;i--){
44             if(b.a[i]>a[i])return 1;
45             if(b.a[i]<a[i])return 0;
46         }
47         return 0;
48     }
49 }A,B,C,tmpl,tmpr,tmpm,one;
50 int T,la,lb;
51 char sa[205],sb[205];
52 int main(){
53     scanf("%d",&T);
54     one=1;
55     while(T--){
56         scanf("%s%s",sa+1,sb+1);
57         la=strlen(sa+1);lb=strlen(sb+1);
58         memset(A.a,0,sizeof A.a);
59         memset(B.a,0,sizeof B.a);
60         A.len=la;B.len=lb;
61         for(int i=1;i<=la;i++)A.a[la-i+1]=sa[i]-'0';
62         for(int i=1;i<=lb;i++)B.a[lb-i+1]=sb[i]-'0';
63         if(A.a[1]%2==0&&B.a[1]%2==0){puts("No");continue;}
64         while(A.a[1]%2==0)A.div();
65         while(B.a[1]%2==0)B.div();
66         while(1){
67             if(A<B){C=A;A=B;B=C;}
68             if(B.len==1&&B.a[1]==0)break;
69             A=A-B;
70             while((A.len!=1||A.a[1]!=0)&&A.a[1]%2==0)A.div();
71         }
72         if(A.len==1&&A.a[1]==1)puts("Yes");
73         else puts("No");
74     }
75     return 0;
76 }
king

T2:数数题,012的序列,问有多少个区间满足区间内最大的数不超过一半

正难则反,考虑有多少个不满足,不符合条件的区间为$j+1~i$,则一定有

$sumi-sumj>(i-j)/2$

$2*sumi-i>2*sumj-j$树状数组啊,于是我就60分gg了

再考虑性质,每往后移动一位,上述的val波动只有可能是1或-1;

于是处理前缀和O(1)转移即可

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define N 5000050
 7 #define LL long long
 8 using namespace std;
 9 LL ans;
10 char s[N];
11 int n,a[N],sum[3][N];
12 int c[2*N],ss;
13 int main(){
14     scanf("%d",&n);
15     scanf("%s",s+1);
16     for(int i=1;i<=n;i++){
17         a[i]=s[i]-'0';
18         sum[0][i]=sum[0][i-1];
19         sum[1][i]=sum[1][i-1];
20         sum[2][i]=sum[2][i-1];
21         sum[a[i]][i]++;
22     }
23     ans=(LL)n*(n+1)/2;
24     for(int t=0;t<3;t++){
25         memset(c,0,sizeof c);
26         c[n+5]++;ss=1;
27         for(int i=1,val,last;i<=n;i++){
28             val=2*sum[t][i]-i+n+5;
29             last=2*sum[t][i-1]-i+1+n+5;
30             if(last==val-1){ans-=ss;}
31             if(last==val+1){ss-=c[last]+c[val];ans-=ss;}
32             c[val]++;
33             ss+=c[val];
34         }
35     }
36     printf("%lld
",ans);
37     return 0;
38 }
snow

T3:codeforces 739E加强版

O(n3)dp很好想,40分到手,然后我就gg了

如果贪心的话肯定是都喂A,也都喂B,但是球可能不够

考虑给每个A球赋一个额外的权值cost,每选一个A球就给最终答案减去cost,二分这个cost,就可以保证最终的A球在范围内,同理可以二分B

O(n3)->O(nlog2)

好像卡eps

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define eps 1e-8
 7 #define N 100500
 8 using namespace std;
 9 int n,na,nb;
10 double p[N],q[N],pq[N];
11 double ff;
12 int num1,num2;
13 bool judge(double x,double y){
14     num1=0,num2=0;ff=0;
15     for(int i=1;i<=n;i++){
16         int o=0;
17         double tmp1=p[i]-x,tmp2=q[i]-y,tmp3=pq[i]-x-y,last=ff;
18         if(last+tmp1>ff-eps){ff=last+tmp1;o=1;}
19         if(last+tmp2>ff-eps){ff=last+tmp2;o=2;}
20         if(last+tmp3>ff-eps){ff=last+tmp3;o=3;}
21         if(o&1)num1++;if(o&2)num2++;
22     }
23 }
24 double l,r,mid;
25 void check(double x){
26     l=0;r=1;
27     while(l+eps<r){
28         mid=(l+r)/2.0;
29         judge(x,mid);
30         if(num2<=nb)r=mid;
31         else l=mid;
32     }
33 }
34 int main(){
35     while(scanf("%d%d%d",&n,&na,&nb)==3){
36         for(int i=1;i<=n;i++)scanf("%lf",&p[i]);
37         for(int i=1;i<=n;i++)scanf("%lf",&q[i]);
38         for(int i=1;i<=n;i++)pq[i]=p[i]+q[i]-p[i]*q[i];
39         double L=0,R=1,MID;
40         while(L+eps<R){
41             MID=(L+R)/2.0;
42             check(MID);
43             judge(MID,r);
44             if(num1<=na)R=MID;
45             else L=MID;
46         }
47         judge(R,r);
48         printf("%0.3f
",ff+R*na+r*nb);
49     }
50     return 0;
51 }
red
原文地址:https://www.cnblogs.com/Ren-Ivan/p/7798511.html