惨。今天聪哥选了2013 多校10做训练,结果一题都没做出来。这个题目是数据结构,正好是我强项
如果只是插入 删除 光标左右移动,那都小菜,用链表全解决,关键是那个Q k 要求 a1到aq的连续子序列和最大(子序列一定要以a1开头)。
然后我用记录每个节点的当前最大和总体最大,这样只要知道第k个是哪个数就可以了,但由于是用的链表,并不知道第k个是哪个。。一开始试了下暴力去扫,结果TL。。
其实我能想到每个点由前一个点过渡最大值,就离答案不远了,既然我不知道当前节点是第几个数,我就手动加一个量,专门记录数量的增减嘛。。然后用一个数组专门记录第几个数的最大值是多少,也可以用向量咯
哎,当时比赛的时候居然没想到
还有种用双桟的方法写的,Q处理一样的,只是用双桟写比链表要好写一些,因为题目只对光标所在处操作,故光标前弄个桟 光标后弄个桟 即可。
代码里真正查询的是 sum数组和v向量,d和ans是未修改代码残留的,没用,其实用向量还是写复杂了,直接另外用个数组记录第几个数的最大值就行了,遇到k直接输出更方便
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 1000000+10; int cnt; int Q,S,T,cur,n; vector<int> v; int sum[N]; struct node { int pre,next; int xi; int d; int ans; } num[N]; void SI() { n++; int x; scanf("%d",&x); sum[n]=sum[n-1]+x; node* now=&num[cnt]; //插入操作 now->pre=cur; now->next=num[cur].next; num[cur].next=cnt; num[now->next].pre=cnt; cur=cnt; cnt++; now->xi=x; now->d=x; now->ans=x; if (now->pre!=S){ node* bf=&num[now->pre]; now->d=bf->d+x; now->ans=now->d; now->ans=max(now->ans,bf->ans); } int r=v.size(); if (now->pre==S){ v.push_back(n); } else{ if ((sum[n])>sum[v[r-1]]){ v.push_back(n); } } } void SD() { if (cur==S) return; int r=v.size(); if (n==v[r-1]) v.pop_back(); n--; node* bf=&num[num[cur].pre]; node* af=&num[num[cur].next]; bf->next=num[cur].next; af->pre=num[cur].pre; if (num[cur].next!=T){ af->d=bf->d+af->xi; af->ans=af->d; af->ans=max(af->ans,bf->ans); } cur=num[cur].pre; } void SL() { if (cur!=S){ int r=v.size(); if (n==v[r-1]) v.pop_back(); n--; cur=num[cur].pre; } } void SR() { if (num[cur].next!=T){ cur=num[cur].next; n++; int r=v.size(); sum[n]=sum[n-1]+num[cur].xi; if (sum[n]>sum[v[r-1]]) v.push_back(n); } } void query() { int k; scanf("%d",&k); int r=v.size(); if (v[r-1]<=k) printf("%d ",sum[v[r-1]]); else { int loc=upper_bound(v.begin(),v.end(),k)-v.begin(); printf("%d ",sum[v[loc-1]]); } } void test() { cout<<"Test:"<<endl; cout<<cur<<endl; for (int i=S;i!=T;i=num[i].next){ cout<<num[i].xi<<" "; } cout<<endl; for (int i=1;i<v.size();i++) cout<<v[i]<<"-"<<sum[v[i]]<<" "; cout<<endl; } int main() { char ch[2]; while (scanf("%d",&Q)!=EOF) { v.clear(); cnt=1; n=0; S=0,T=N-1; sum[S]=sum[T]=0; v.push_back(S); num[S].next=T; num[S].ans=num[S].d=num[S].xi=0; num[T].ans=num[T].d=num[T].xi=0; num[T].pre=S; cur=S; while (Q--){ //test(); scanf("%s",ch); if (ch[0]=='I'){ SI(); } else if (ch[0]=='D'){ SD(); } else if (ch[0]=='L'){ SL(); } else if (ch[0]=='R'){ SR(); } else{ query(); } } } return 0; }