式子变形类题目
遇到这种问题一定要变形式子
给定 n 个石子,编号为 1∼n。
其中第 i 个石子的价值为 ai。
你需要从中任意挑选若干个石子,并将挑选好的石子按照编号从小到大的顺序排成一排。
选中的石子在排好序后需要满足,对于任意两个相邻的石子(不妨设它们的编号为 x,y,x−y=ax−ay 均成立。
例如,当有 n=8 个石子,石子价值分别为 [3,4,4,6,6,7,8,9] 时,一些合理的选择方案如下:
- 选择 1,2,4 号石子,它们的价值分别为 3,4,6。1 号石子与 2 号石子相邻,2−1=4−3 成立。2 号石子与 4 号石子相邻,4−2=6−4 成立。所以方案合理。
- 选择 7 号石子。可以只选择一个石子,此时选取任何石子均为合理方案。
你的选择方案不仅需要合理,而且还要使得选中石子的价值总和尽可能大。
请计算并输出价值总和的最大可能值。
输入格式
第一行包含整数 n。
第二行包含 n 个整数a1,a2,…,an。
输出格式
一个整数,表示选中石子的价值总和的最大可能值。
数据范围
前三个测试点满足 1≤n≤10。
全部测试点满足 1≤n≤2×10^5,1≤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
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; } }