cf 567c 思维

题意:要求计算出一个长为n的序列中,长度为3的子序列且这个子序列能构成公比为k的等比数列的总个数。
假设某一个等比以p结尾,那么他的贡献,就来自于,p/k,p/k/k,那么如何同届呢。我们可以发现,以p结尾的子序列,贡献和为,在第一个p/k前面有多少个p/k/k,第二个p/k前面有多少个p/k/k,。。。。。以此类推。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<climits>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    //#include<regex>
    #include<cstdio>
    #define up(i,a,b)  for(int i=a;i<b;i++)
    #define dw(i,a,b)  for(int i=a;i>b;i--)
    #define upd(i,a,b) for(int i=a;i<=b;i++)
    #define dwd(i,a,b) for(int i=a;i>=b;i--)
    //#define local
    typedef long long ll;
    const double esp = 1e-6;
    const double pi = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const int inf = 1e9;
    using namespace std;
    int read()
    {
    	char ch = getchar(); int x = 0, f = 1;
    	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    	return x * f;
    }
    typedef pair<int, int> pir;
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lrt root<<1
    #define rrt root<<1|1
    int n, k;
    const int N = 2e5 + 10;
    ll a[N];
    map<ll, ll>mp,cnt;
    int main() {
    	n = read(), k = read();
    	up(i, 0, n)a[i] = read();
    	if (k == 1)
    	{
    		ll ans = 0;
    		up(i, 0, n)mp[a[i]]++;
    		up(i, 0, n)if (mp[a[i]] > 2)ans += mp[a[i]] * 1ll * (mp[a[i]] - 1)*(mp[a[i]] - 2) / 6,mp[a[i]]=0;
    		cout << ans << endl;
    		return 0;
    	}
    	ll ans = 0;
    	int zero = 0;
    	up(i, 0, n)
    	{
    		cnt[a[i]]++;
    		if (a[i] % k == 0 && a[i] != 0)
    		{
    			mp[a[i] * k] += cnt[a[i] / k];
    		}
    		else if (a[i] == 0)zero++;
    		ans += mp[a[i]];
    	}
    	cout << ans + (zero) * 1ll * (zero - 1)*(zero - 2) / 6 << endl;
    }
posted @ 2019-09-25 19:40  LORDXX  阅读(249)  评论(0编辑  收藏  举报