HDU—4699 Editor 双向链表+子集和

惨。今天聪哥选了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\n",sum[v[r-1]]);
    else {
        int loc=upper_bound(v.begin(),v.end(),k)-v.begin();
        printf("%d\n",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;
}

 

 

posted @ 2014-07-05 22:09  KRisen  阅读(435)  评论(0编辑  收藏  举报