式子变形类题目

遇到这种问题一定要变形式子

传送门:

给定 n 个石子,编号为 1∼n

其中第 i 个石子的价值为 ai

你需要从中任意挑选若干个石子,并将挑选好的石子按照编号从小到大的顺序排成一排。

选中的石子在排好序后需要满足,对于任意两个相邻的石子(不妨设它们的编号为 x,yx−y=ax−ay 均成立。

例如,当有 n=8 个石子,石子价值分别为 [3,4,4,6,6,7,8,9] 时,一些合理的选择方案如下:

  • 选择 1,2,4 号石子,它们的价值分别为 3,4,61 号石子与 2 号石子相邻,2−1=4−3 成立。2 号石子与 4 号石子相邻,4−2=6−4 成立。所以方案合理。
  • 选择 7 号石子。可以只选择一个石子,此时选取任何石子均为合理方案。

你的选择方案不仅需要合理,而且还要使得选中石子的价值总和尽可能大。

请计算并输出价值总和的最大可能值。

输入格式

第一行包含整数 n

第二行包含 n 个整数a1,a2,…,an

输出格式

一个整数,表示选中石子的价值总和的最大可能值。

数据范围

前三个测试点满足 1≤n≤10
全部测试点满足 1≤n≤2×10^51≤ai≤4×10^5

输入样例1:

6

10 7 1 9 10 15

输出样例1:

26

输入样例2:

1

400000

输出样例2:

400000

输入样例3:

7

8 9 26 11 12 29 14

输出样例3:

55

 

 

 

 

这个题是一个推式子的题目:首先你看到这个式子x−y=a[x]−a[y],一定要想到变形a[x]-x==a[y]-y所以这个 a[x]-x 为一个定值

令a[x]−x=t,所以令mp[t]+=a[x],然后最后求出最大的mp[t]就行了,

#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=3e5+100;
int a[maxn];
map<int,ll>mp;
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        mp[a[i]-i]+=a[i];
    }
    ll ans=0;
    for(auto x:mp){
        ans=max(ans,x.second);
    }
    cout<<ans<<endl;
    
}

然后一个cf上的题目和这个很像,就是这个题:链接

 

You are given an array a of n integers. Count the number of pairs of indices (i,j) such that i<j and aj−ai=j−i.

Input

The first line contains one integer t (1≤t≤10^4). Then t test cases follow.

The first line of each test case contains one integer n (1≤n≤2*10^5).

The second line of each test case contains n integers a1,a2,…,an (1≤ai≤n) — array a.

It is guaranteed that the sum of nn over all test cases does not exceed 2*10^5.

Output

For each test case output the number of pairs of indices(i,j) such that i<j and aj−ai=j−i.

 

4
6
3 5 1 4 6 6
3
1 2 3
4
1 3 3 4
6
1 6 3 4 5 6
output
Copy
1
3
3
10

这个题和上一个题是一样的,就是看到这个a[j]-a[i]=j-i,然后你可以变一下式子,然后就变成了a[j]-j==a[i]-i然后令
a[i]-i=b[i],就是求i<j然后j后面有几个b[j]
#include<iostream>
#include<algorithm>
#include<map>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=3e5+100;
int a[maxn];
int b[maxn];
map<int,int>mp;
int main(){
    int t;
    cin>>t;
    while(t--){
        mp.clear();
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            b[i]=a[i]-i;
        }
        ll ans=0;
        for(int i=1;i<=n;i++){
            ans+=mp[b[i]];
            mp[b[i]]++;
        }
        cout<<ans<<endl;
    }
} 

 

 

posted @ 2021-07-17 20:59  lipu123  阅读(86)  评论(0)    收藏  举报