DP/单调队列优化
呃……环形链求最大k子段和。
首先拆环为链求前缀和……
然后单调队列吧<_<,裸题没啥好说的……
WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……sigh)
1 //HDOJ 3415 2 #include<queue> 3 #include<cmath> 4 #include<vector> 5 #include<cstdio> 6 #include<cstring> 7 #include<cstdlib> 8 #include<iostream> 9 #include<algorithm> 10 #define rep(i,n) for(int i=0;i<n;++i) 11 #define F(i,j,n) for(int i=j;i<=n;++i) 12 #define D(i,j,n) for(int i=j;i>=n;--i) 13 #define pb push_back 14 #define CC(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 int getint(){ 17 int v=0,sign=1; char ch=getchar(); 18 while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();} 19 while(isdigit(ch)) {v=v*10+ch-'0'; ch=getchar();} 20 return v*sign; 21 } 22 typedef long long LL; 23 const int N=100010,INF=~0u>>2; 24 const double eps=1e-8; 25 /*******************template********************/ 26 27 int a[N],f[N],q[N+N],s[N]; 28 deque<int>Q; 29 void work(){ 30 int n=getint(),k=getint(); 31 s[0]=0; 32 F(i,1,n){ 33 a[i]=getint(); 34 s[i]=s[i-1]+a[i]; 35 } 36 F(i,n+1,n+k-1) s[i]=s[i-1]+a[i-n]; 37 int m=n+k-1; 38 39 int _sum=-INF,pos=0,end=0; 40 Q.clear(); 41 F(i,1,m){ 42 while(!Q.empty() && s[Q.back()]>s[i-1]) Q.pop_back(); 43 while(!Q.empty() && Q.front()<(i-k)) Q.pop_front(); 44 Q.push_back(i-1); 45 if (s[i]-s[Q.front()]>_sum){ 46 _sum=s[i]-s[Q.front()]; 47 pos=Q.front()+1; 48 end=i; 49 } 50 } 51 printf("%d %d %d ",_sum,pos,(end>n) ? (end-n) : end); 52 } 53 int main(){ 54 int T=getint(); 55 while(T--) work(); 56 return 0; 57 }