1320A. Journey Planning
Meaning:
Given a sequence ai.
Find a subsequence from which I > J, I-J = a [i] - a [J].
What is the maximum sum of such subsequences?
Idea:
i-j=a[i]-a[j], i.e. i-a[i]=j-a[j].
The map then records the same sum of values. Take the maximum.
It's a simple formula deformation. At the beginning, I still thought about violent search, dp..
Code:
const int N = 200010, mod = 1e9+7; ll T, n, m, a[N]; ll sum,ans; bool f[N]; int main(){ Ios; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) { int x=i-a[i]; mp[x]+=a[i]; if(mp[x]>ans) ans=mp[x]; } cout<<ans; return 0; }
Experience:
When I see the formula given later, I'll deform it first.
Don't say what he says. Follow him in.
1312C. Adding Powers
Meaning:
Given k, for the 0 array a with length n, judge whether it can be transformed into array b through the following operations?
For the ith operation (i starts from 0):
1. Select a position and set the value + = k^i;
2. Skip this operation.
The operation can be stopped at any time.
Idea:
in other words:
For each number in the target array, it should be able to be converted into the sum of powers of k. And the required power of n numbers cannot be repeated.
Therefore, for each number, we must find the maximum power of k (if it is not the maximum, there must be a repeated power for this number)
Traversing each number, the map records the number of power occurrences. If a power occurs multiple times, it cannot be satisfied.
Note: the log(x) function has precision error for large numbers.
Code:
const int N = 200010, mod = 1e9+7; int T, n, m, a[N]; int k,flag; int p[N]; void pd(int x) { while(x) { int t; for(int i=0;i<=x;i++){ if(pow(k,i)<=x) t=i; else break; } if(mp[t]){ flag=1;return; } else mp[t]=1; x-=pow(k,t); } } signed main(){ Ios; cin>>T; while(T--) { flag=0; cin>>n>>k; mp.clear(); for(int i=1;i<=n;i++) { int x;cin>>x; if(x) pd(x); } if(flag) cout<<"No\n"; else cout<<"Yes\n"; } return 0; }
289B. Polo the Penguin and Matrix (absolute value)
Meaning:
Given number k. For n numbers, you can select one number + k or - k for each operation.
Q, how many operations at least can make all numbers equal? If not, output - 1.
Idea:
For a number, adding or subtracting k is constant for the value of its modulus k.
Therefore, if the values of two digital analog k are different, the two values cannot be made equal by any operation.
Therefore, there is a solution only when the values of all digital modules k are equal.
How to get the optimal solution?
To minimize the number of operations is to minimize the value of | x-a1|/k+|x-a2|/k+|x-a3|/k+...+|x-an|/k = (|x-a1|+|x-a2|+|x-a3|+...+|x-an|)/k, and X is the final equal number.
Then, find the minimum of | x-a1|+|x-a2|+|x-a3|+...+|x-an |. As we have seen before, the optimal solution of X is the median a[n/2+1] of ai.
Code:
const int N = 200010, mod = 1e9+7; int T, n, m, a[N]; int main(){ Ios; int k; cin>>n>>m>>k; int flag=0,cnt=0,t; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cnt++; cin>>a[cnt]; if(cnt==1) t=a[1]%k; else if(a[cnt]%k!=t) flag=1; } } if(flag){ cout<<-1;return 0; } n*=m; sort(a+1,a+n+1); int x=a[n/2+1]; int ans=0; for(int i=1;i<=n;i++) { ans+=abs(x-a[i])/k; } cout<<ans; return 0; }
Extension:
What if you can select multiple numbers + k or - k at a time?
What if you choose a submatrix + k or - k in a two-dimensional matrix at a time?
1201c. Maximum medium (Analog)
Meaning:
Given a sequence of length N, given the number k. (n is an odd number)
There are k operations at most. You can select a position for each operation and increase the number in this position by 1.
Q: what is the maximum median of the series?
Idea:
Because it is the median, only the following n/2+1 bits have an impact on the median, so k operations should be put behind.
To maximize the minimum value in the following n/2+1 positions, put all numbers in the priority queue and take the first of the queue for operation each time.
But k is the largest 1e9, so this scheme is not feasible.
This problem has a feature that only 1 is added for each operation.
So you can pile it up slowly from small to large. Compare the following values with the previous values to see if they can be supplemented, including all the previous numbers.
If you can make it up, compare it with the next one; If not, see how much you can make up at most.
The minimum value after supplement is the answer.
Code:
signed main(){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>b[i]; sort(b+1,b+n+1); int cnt=0; for(int i=n/2+1;i<=n;i++){ cnt++; a[cnt]=b[i]; } n=cnt; int ans=0; for(int i=1;i<n;i++) { if(m>=i*(a[i+1]-a[i])){ //Open long long m-=i*(a[i+1]-a[i]); a[i]=a[i+1]; ans=a[i]; } else { int x=m/i; m=0; ans=a[i]+x; break; } } if(m){ int x=m/n; ans=a[n]+x; } cout<<ans; return 0; }