【题解】[Codeforces 1400D] Zigzags

题目链接

题意

今有一序列 \(a\),统计满足如下条件的四元组 \((i,j,k,l)\) 的个数:

  • \(1\leq i < j < k < l\leq n\)
  • \(a_i=a_k,a_j=a_l\)

\(n\leq 3\times 10^3\)

题解

(正在尝试找出自己适合刷 CF 什么难度的题,感觉这道还是太简单了(?))(就当练手速吧(雾))

首先统计哪些 \((i,j)\) 满足 \(a_i=a_j\),对其求前缀和。再枚举 \((i,k)\),查询有多少 \((j,l)\) 符合要求。

代码:

#include<bits/stdc++.h>
using namespace std;
int getint(){
    int ans=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        ans=ans*10+c-'0';
        c=getchar();
    }
    return ans*f;
}
const int N=3e3+10;
int a[N];
int b[N][N],s[N][N];
int calc(int x1,int x2,int y1,int y2){
    return s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1];
}
int main(){
    int T=getint();
    while(T --> 0){
        int n=getint();
        for(int i=1;i<=n;i++){
            a[i]=getint();
            memset(b[i],0,sizeof(int)*(n+1));
            memset(s[i],0,sizeof(int)*(n+1));
        }
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                if(a[i]==a[j])b[i][j]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+b[i][j];
        long long ans=0;
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                if(b[i][j])
                    ans+=calc(i+1,j-1,j+1,n);
        printf("%lld\n",ans);
    }
}

posted @ 2020-11-02 10:00  破壁人五号  阅读(148)  评论(0编辑  收藏  举报