蓝桥集训之递增三元组

蓝桥集训之递增三元组

  • 核心思想:前缀和

    • 因为b是中间数 遍历b时 ac没有约束关系
    • 所以遍历b 然后求出a有多少比b小的 c有多少比b大的 a*c即可
    • 用哈希表将a[i]中每个数出现次数记录
    • 求其前缀 得到s[i]为 <=i的个数
    • 分别用as和cs记录比b[i]小的数的个数 简化代码
  •   #include <cstdio>
      #include <cstring>
      #include <iostream>
      #include <algorithm>
      using namespace std;
      typedef long long LL;
      const int N = 100010;
      
      int a[N],b[N],c[N];
      int as[N],cs[N];
      int cnt[N],s[N];  //前缀和数组
      
      int main()
      {
          int n;
          cin>>n;
          for(int i=0;i<n;i++) cin>>a[i],a[i]++;
          for(int i=0;i<n;i++) cin>>b[i],b[i]++;    
          for(int i=0;i<n;i++) cin>>c[i],c[i]++;
          
          for(int i=0;i<n;i++) cnt[a[i]] ++;  //哈希表记录每个数出现次数
          for(int i=1;i<N;i++)  s[i] = s[i-1] + cnt[i];  //求前缀 s[i]表示<=i的数的个数
          for(int i=0;i<n;i++) as[i] = s[b[i] - 1];  //as[i]表示对应小于b[i]的元素个数
          
          memset(cnt,0,sizeof cnt);
          memset(s,0,sizeof s);
          
          for(int i=0;i<n;i++) cnt[c[i]] ++;
          for(int i=1;i<N;i++)  s[i] = s[i-1] + cnt[i];
          for(int i=0;i<n;i++) cs[i] = s[N-1] - s[b[i]];  //cs[i]表示对应大于b[i]的元素个数
          
          LL res=0;
          for(int i=0;i<n;i++) res += (LL)as[i] * cs[i];  //可能爆int
          
          cout<<res;
      }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光男孩01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值