Codeforces Round #719 (Div. 3) D. Same Differences 题解

一、算法分析

很经典的做法,把原来的 a j − a i = j − i a_j-a_i=j-i ajai=ji进行移项,变成 a j − j = a i − i a_j-j=a_i-i ajj=aii,从而生成一个新的数组 b i = a i − i b_i=a_i-i bi=aii,对于新数组,只需要统计某个数 b i b_i bi之前有多少个和其相等的数即可。

对于这种题目,要求就是要做得快,代码要一气呵成尽可能不要出错,要思考缜密。比如这道题的 b b b数组元素下标就可能小于0,那么就要用到偏移量或者是用map数组。

二、代码及注释

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #define LL long long
 6 using namespace std;
 7 const int N=400050;
 8 const int base=N/2;                        //偏移量
 9 int s[N];
10 int n;
11 LL res;
12 int main(){
13     
14     int T;
15     scanf("%d",&T);
16     while(T--){
17         res=0;
18         memset(s,0,sizeof(s));
19         scanf("%d",&n);
20         for(int i=1;i<=n;i++){
21             int x;
22             scanf("%d",&x);
23             x+=base-i;
24             res+=s[x];
25             s[x]++;
26         }
27         printf("%lld\n",res);
28     }
29     
30     
31     
32     return 0;
33     
34 }

(之前写在小号里了,现在大号找回来了,所以再搬回来汇总一下)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值