题意:给你一个函数f(x),一个数列,你有一次操作机会,能操作数列的一个区间,让区间里所有数都变成f(x),也可以不变。问操作完之后最大子段和是多少。
思路:求出每个f(x)和 x 的差,有正有负,题目就变成了这个序列的最大子段和问题,O(n)扫一遍就搞定了。
2 10000 9999 5 1 9999 1 9999 1
19999 22033
#include <iostream> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string> #include <string.h> #include <algorithm> #include <vector> #include <queue> #include <iomanip> #include <time.h> #include <set> #include <map> #include <stack> using namespace std; typedef long long LL; const int INF=0x7fffffff; const int MAX_N=10000; int n; int A[100009]; int fa[100009]; int f(int x){ return (1890*x+143)%10007; } int main(){ while(scanf("%d",&n)!=EOF){ int sum=0; int sum2=0; int cursum=0; for(int i=0;i<n;i++){ scanf("%d",&A[i]); sum+=A[i]; fa[i]=f(A[i])-A[i]; if(fa[i]>0){ cursum+=fa[i]; sum2=max(sum2,cursum); } else{ cursum+=fa[i]; if(cursum<0){ cursum=0; } } } printf("%d\n",sum+sum2); } return 0; }