Codeforces Round #Pi (Div. 2) C. Geometric Progression

C. Geometric Progression


题意:

给出一个序列找出多少个长度为三子序列的公差为k(a,a*k,a*k*k)

从后向前更新,分别更新当前每个数a出现的次数、i和i以后所有i*k数量的和、累i后i*k*k的所有数量和的和

例如:(k=3,更新到红3情况)

1 3 9 3 9

<----------

                     前      后         表达式
num[3][2]     0       0           num[3][2]+=num[9][1];
num[3][1]     1       3           num[3][1]+=num[9][0];
num[3][0]     1       2           num[3][0]++;
</pre><p></p><p></p><p><span style="color:#0000ee"><u></u></span></p><p></p><pre name="code" class="cpp">#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#define ll __int64
#define INF 1e9
#define maxn 1000005
using namespace std;
ll a[maxn];
ll b[maxn];
ll ser[maxn];
ll num[maxn][3];
/**
num[i][0]存储i的数量
num[i][1]累加当前i,后面i*k的数量
num[i][2]累加i*k后i*k*k的数量
从后往前更新
最后累加num[i][2]即为所求结果
*/
int A;
int find(ll num){
    return lower_bound(ser,ser+A,num)-ser;
}
int main(){
    ll n,k;
    while(~scanf("%lld%lld",&n,&k)){
        A=0;
        for(int i=0;i<n;i++){
            scanf("%lld",&a[i]);
            b[i]=a[i];
        }
        sort(b,b+n);
        ser[A++]=b[0];
        for(int i=1;i<n;i++)
            if(b[i]!=ser[A-1]) ser[A++]=b[i];
        int p1,p2,p3;
        memset(num,0,sizeof(num));
        for(int i=n-1;i>=0;i--){
            p1=find(a[i]);
            p2=find(a[i]*k);
            p3=find(a[i]*k*k);
            if(p2<A&&ser[p2]==a[i]*k){
                num[p1][2]+=num[p2][1];
                num[p1][1]+=num[p2][0];
            }
            num[p1][0]++;
        }
        ll ans=0;
        for(int i=0;i<A;i++)
            ans+=num[i][2];
        printf("%lld\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值