• 9.6题解


    T1

    这题大家都会做,$gcd(n,m)=1$就可以让每个人都扔一次西瓜,不是一就不可以,关键在于高精度的灵活运用,这题可以打高精取模,但是我不会,所以我们选择二进制下计算$gcd$,大致流程如下

    1.$n{\%}2==0$,$m{\%}2==0$,对于这道不用实际求出gcd的题来说,直接$return$ $false$就可以了

    2.$n{\%}2==1$或$m{\%}2==1$,那就高精除低精,给偶数除2,直至偶数变成奇数

    3.$n{\%}2==1$且$m{\%}2==1$,留下较小的数,高精减高精,大数减小数,返回第二步

    边界条件就是一个数变成了1或0,变成一gcd肯定是1,变成0的话,gcd取决于另一个数

    由于不断处以二,可以保证复杂度在$log$级别

     1 #include<iostream>
     2 #include<cstring>
     3 #include<string>
     4 #include<cstdio>
     5 #define maxx 110
     6 using namespace std;
     7 int t;
     8 struct node{
     9     int a[maxx],len;
    10 }nn,mm;
    11 char a[maxx],b[maxx];
    12 bool cmp(node x,node y)//1:x>=y 0:x<y
    13 {
    14     if(x.len>y.len)  return 1;
    15     else if(x.len<y.len)  return 0;
    16     else
    17     {
    18         for(int i=x.len;i>=1;--i)
    19         {
    20             if(x.a[i]>y.a[i])  return 1;
    21             else if(x.a[i]<y.a[i])  return 0;
    22         }
    23     }
    24     return 1;
    25 }
    26 node gjj(node x,node y)//x-y
    27 {
    28     for(int i=1;i<=y.len;++i)
    29     {
    30         if(x.a[i]-y.a[i]>=0)  x.a[i]-=y.a[i];
    31         else  {x.a[i+1]--;  x.a[i]+=10;  x.a[i]-=y.a[i];}
    32     }
    33     while(x.a[x.len]==0&&x.len!=1)  x.len--;
    34     return x;
    35 }
    36 node gjc(node x)
    37 {
    38     int carry=0;
    39     for(int i=x.len;i>=1;--i)
    40     {
    41         int tmp=x.a[i];
    42         x.a[i]=(carry+x.a[i])/2;
    43         carry=(carry+tmp)%2;  carry*=10;
    44     }
    45     while(x.a[x.len]==0&&x.len!=1)  x.len--;
    46     return x;
    47 }
    48 void out(node x)
    49 {
    50     for(int i=x.len;i>=1;--i)  cout<<x.a[i];
    51     cout<<" ";
    52 }
    53 bool check()
    54 {
    55     if(nn.len==1&&nn.a[nn.len]==1)  {printf("Yes
    ");  return 1;}
    56     if(mm.len==1&&mm.a[mm.len]==1)  {printf("Yes
    ");  return 1;}
    57     if(nn.len==1&&nn.a[1]==0)
    58     {
    59         if(mm.len==1&&mm.a[1]==1)  {printf("Yes
    ");  return 1;}
    60         else  {printf("No
    ");  return 1;}
    61     }
    62     if(mm.len==1&&mm.a[1]==0)
    63     {
    64         if(mm.len==1&&mm.a[1]==1)  {printf("Yes
    ");  return 1;}
    65         else  {printf("No
    ");  return 1;}
    66     }
    67     return 0;
    68 }
    69 int main()
    70 {
    71     scanf("%d",&t);
    72     while(t--)
    73     {
    74         scanf("%s%s",a+1,b+1);
    75         nn.len=strlen(a+1);  mm.len=strlen(b+1);
    76         for(int i=1;i<=nn.len;++i)  nn.a[nn.len-i+1]=a[i]-'0';
    77         for(int i=1;i<=mm.len;++i)  mm.a[mm.len-i+1]=b[i]-'0';
    78         if(a[nn.len]%2==0&&b[mm.len]%2==0)  {printf("No
    ");  continue;}
    79         while(1)
    80         {
    81             if(check())  break;
    82             while(nn.a[1]%2==0)  nn=gjc(nn);
    83             if(check())  break;
    84             while(mm.a[1]%2==0)  mm=gjc(mm);
    85             if(check())  break;
    86             if(!cmp(nn,mm))  swap(nn,mm);
    87             nn=gjj(nn,mm);
    88         }
    89     }
    90     return 0;
    91 }
    swap数组用结构体封装好评

    T2

    考虑一种简单的情况,如果序列里只有0和1,那我们把0看作-1,1看作+1,合法序列的区间和肯定且必须就是0,那如果我们记录前缀和,前缀和相等的两个右端点之间的区间就是合法区间

    如果加进2来呢,考虑容斥,不合法的情况只有3种,区间里0超过一半,1超过一半,2超过一半,假设我们求0超过一半的,那么1,2都同理,求0超过一半的,我们把0看作-1,1和2都看作+1,那要找的非法区间就是区间和小于0的,转化到前缀和上,其实就是形成逆序对的前缀和,树状数组就可以搞定

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define ll long long
     5 #define maxn 5001000
     6 using namespace std;
     7 int n;
     8 ll ans,tot;
     9 int a[maxn],c1[maxn*3],c2[maxn*3],c3[maxn*3];
    10 int qz[maxn][3];
    11 char s[maxn];
    12 int lowbit(int x)
    13 {
    14     return x&(-x);
    15 }
    16 void add(int c[],int pos)
    17 {
    18     for(;pos<=3*n+1;pos+=lowbit(pos))  c[pos]++;
    19 }
    20 ll query(int c[],int pos)
    21 {
    22     ll ans=0;
    23     for(;pos>0;pos-=lowbit(pos))  ans+=1ll*c[pos];
    24     return ans;
    25 }
    26 int main()
    27 {
    28     scanf("%d",&n);  scanf("%s",s+1);
    29     for(int i=1;i<=n;++i)
    30     {
    31         for(int j=0;j<=2;++j)  qz[i][j]=qz[i-1][j];
    32         a[i]=s[i]-'0';  qz[i][a[i]]++;
    33     }
    34     for(int i=1;i<=n;++i)
    35     {
    36         
    37         add(c1,qz[i-1][0]*2-i+n+2);  tot+=query(c1,qz[i][0]*2-i+n);
    38         add(c2,qz[i-1][1]*2-i+n+2);  tot+=query(c2,qz[i][1]*2-i+n);
    39         add(c3,qz[i-1][2]*2-i+n+2);  tot+=query(c3,qz[i][2]*2-i+n);
    40     }
    41     ans=1ll*n*(n+1)/2;  ans-=tot;
    42     printf("%lld
    ",ans);
    43     return 0;
    44 }
    View Code

    T3

    期望题,又一次咕咕咕

  • 相关阅读:
    nginx&http 第二章 ngx 事件event处理 数据结构
    nginx&http 第二章 ngx启动多进程
    PF_PACKET抓包mmap
    PF_PACKET&&tcpdump
    tcpack--3快速确认模式- ack状态发送&清除
    tcpack---1简述
    tcpack--3快速确认模式
    tcpack--4延时ack
    linux tcp Nagle算法,TCP_NODELAY和TCP_CORK 转载
    tcpack----- 2sack dack
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11558710.html
Copyright © 2020-2023  润新知