POJ 2750: Potted Flower

来源:互联网 发布:淘宝怎么截图发给别人 编辑:程序博客网 时间:2024/05/03 19:56

题目链接:http://poj.org/problem?id=2750


题意:

在一个环状数列上动态修改某一元素的值,

每次询问最大子串和。

数据保证答案始终是正的,

注意题目要求子串长度必须小于原串长度。


算法:

线段树的简单应用。

注意答案分两种情况:

1)直接在线段树上求最长子序列和(题目要求子串不得等于原串,可以用小技巧处理,详见代码)

2)求所有元素和,再减去最小非空子串和


代码如下:

#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cstring>#include<string>#include<climits>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define eps 1e-8using namespace std;typedef pair<int,int> PII;const int MAXN=110000;int tolsum;int a[MAXN];int sum[MAXN<<2];int lmin[MAXN<<2],rmin[MAXN<<2],mmin[MAXN<<2];int lmax[MAXN<<2],rmax[MAXN<<2],mmax[MAXN<<2];void pushup(int rt) {    sum[rt]=sum[rt<<1]+sum[rt<<1|1];    lmin[rt]=min(lmin[rt<<1],sum[rt<<1]+lmin[rt<<1|1]);    rmin[rt]=min(rmin[rt<<1|1],rmin[rt<<1]+sum[rt<<1|1]);    mmin[rt]=min(mmin[rt<<1],mmin[rt<<1|1]);    mmin[rt]=min(mmin[rt],rmin[rt<<1]+lmin[rt<<1|1]);    rmax[rt]=max(rmax[rt<<1|1],rmax[rt<<1]+sum[rt<<1|1]);    lmax[rt]=max(lmax[rt<<1],sum[rt<<1]+lmax[rt<<1|1]);    mmax[rt]=max(mmax[rt<<1],mmax[rt<<1|1]);    mmax[rt]=max(mmax[rt],rmax[rt<<1]+lmax[rt<<1|1]);}void build(int l, int r, int rt) {    if(l==r) {        scanf("%d",&a[l]);        tolsum+=a[l];        sum[rt]=rmax[rt]=lmax[rt]=mmax[rt]=rmin[rt]=lmin[rt]=mmin[rt]=a[l];        return;    }    int mid=(l+r)>>1;    build(l,mid,rt<<1);    build(mid+1,r,rt<<1|1);    pushup(rt);}void update(int l, int r, int x, int c, int rt) {    if(l==r) {        sum[rt]=rmax[rt]=lmax[rt]=mmax[rt]=rmin[rt]=lmin[rt]=mmin[rt]=c;        return;    }    int mid=(l+r)>>1;    if(x<=mid) {        update(l,mid,x,c,rt<<1);    } else {        update(mid+1,r,x,c,rt<<1|1);    }    pushup(rt);}pair<PII,PII> query(int l, int r, int L, int R, int rt) {    if(L<=l&&r<=R) {        return make_pair(make_pair(sum[rt],mmax[rt]),make_pair(lmax[rt],rmax[rt]));    }    pair<PII,PII> tmp,tmp1,tmp2;    tmp1.first.first=tmp1.first.second=tmp1.second.first=tmp1.second.second=0;    tmp2.first.first=tmp2.first.second=tmp2.second.first=tmp2.second.second=0;    int mid=(l+r)>>1;    if(L<=mid) {        tmp1=query(l,mid,L,R,rt<<1);    }    if(R>mid) {        tmp2=query(mid+1,r,L,R,rt<<1|1);    }    tmp.first.first=tmp1.first.first+tmp2.first.first;    tmp.second.first=max(tmp1.second.first,tmp1.first.first+tmp2.second.first);    tmp.second.second=max(tmp2.second.second,tmp1.second.second+tmp2.first.first);    tmp.first.second=max(tmp1.first.second,tmp2.first.second);    tmp.first.second=max(tmp.first.second,tmp1.second.second+tmp2.second.first);    return tmp;}int main() {    int n;    while(scanf("%d",&n)==1) {        tolsum=0;        build(0,n-1,1);        int m;        scanf("%d",&m);        while(m--) {            int x,c;            scanf("%d%d",&x,&c);            x--;            update(0,n-1,x,c,1);            tolsum+=c-a[x];            a[x]=c;            printf("%d\n",max(max(query(0,n-1,0,n-2,1).first.second,query(0,n-1,1,n-1,1).first.second),tolsum-mmin[1]));        }    }    return 0;}


soj3040与此题类似,代码如下:

#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cstring>#include<string>#include<climits>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define eps 1e-8using namespace std;typedef pair<int,int> PII;const int MAXN=110000;int tolsum;int a[MAXN];int sum[MAXN<<2];int lmin[MAXN<<2],rmin[MAXN<<2],mmin[MAXN<<2];int lmax[MAXN<<2],rmax[MAXN<<2],mmax[MAXN<<2];void pushup(int rt) {    sum[rt]=sum[rt<<1]+sum[rt<<1|1];    lmin[rt]=min(lmin[rt<<1],sum[rt<<1]+lmin[rt<<1|1]);    rmin[rt]=min(rmin[rt<<1|1],rmin[rt<<1]+sum[rt<<1|1]);    mmin[rt]=min(mmin[rt<<1],mmin[rt<<1|1]);    mmin[rt]=min(mmin[rt],rmin[rt<<1]+lmin[rt<<1|1]);    rmax[rt]=max(rmax[rt<<1|1],rmax[rt<<1]+sum[rt<<1|1]);    lmax[rt]=max(lmax[rt<<1],sum[rt<<1]+lmax[rt<<1|1]);    mmax[rt]=max(mmax[rt<<1],mmax[rt<<1|1]);    mmax[rt]=max(mmax[rt],rmax[rt<<1]+lmax[rt<<1|1]);}void build(int l, int r, int rt) {    if(l==r) {        scanf("%d",&a[l]);        tolsum+=a[l];        sum[rt]=rmax[rt]=lmax[rt]=mmax[rt]=rmin[rt]=lmin[rt]=mmin[rt]=a[l];        return;    }    int mid=(l+r)>>1;    build(l,mid,rt<<1);    build(mid+1,r,rt<<1|1);    pushup(rt);}void update(int l, int r, int x, int c, int rt) {    if(l==r) {        sum[rt]=rmax[rt]=lmax[rt]=mmax[rt]=rmin[rt]=lmin[rt]=mmin[rt]=c;        return;    }    int mid=(l+r)>>1;    if(x<=mid) {        update(l,mid,x,c,rt<<1);    } else {        update(mid+1,r,x,c,rt<<1|1);    }    pushup(rt);}pair<PII,PII> query1(int l, int r, int L, int R, int rt) {    if(L<=l&&r<=R) {        return make_pair(make_pair(sum[rt],mmax[rt]),make_pair(lmax[rt],rmax[rt]));    }    pair<PII,PII> tmp,tmp1,tmp2;    int mid=(l+r)>>1;    if(R<=mid) {        return query1(l,mid,L,R,rt<<1);    }    if(L>mid) {        return query1(mid+1,r,L,R,rt<<1|1);    }    if(L<=mid) {        tmp1=query1(l,mid,L,R,rt<<1);    }    if(R>mid) {        tmp2=query1(mid+1,r,L,R,rt<<1|1);    }    tmp.first.first=tmp1.first.first+tmp2.first.first;    tmp.second.first=max(tmp1.second.first,tmp1.first.first+tmp2.second.first);    tmp.second.second=max(tmp2.second.second,tmp1.second.second+tmp2.first.first);    tmp.first.second=max(tmp1.first.second,tmp2.first.second);    tmp.first.second=max(tmp.first.second,tmp1.second.second+tmp2.second.first);    return tmp;}pair<PII,PII> query2(int l, int r, int L, int R, int rt) {    if(L<=l&&r<=R) {        return make_pair(make_pair(sum[rt],mmin[rt]),make_pair(lmin[rt],rmin[rt]));    }    pair<PII,PII> tmp,tmp1,tmp2;    int mid=(l+r)>>1;    if(R<=mid) {        return query2(l,mid,L,R,rt<<1);    }    if(L>mid) {        return query2(mid+1,r,L,R,rt<<1|1);    }    if(L<=mid) {        tmp1=query2(l,mid,L,R,rt<<1);    }    if(R>mid) {        tmp2=query2(mid+1,r,L,R,rt<<1|1);    }    tmp.first.first=tmp1.first.first+tmp2.first.first;    tmp.second.first=min(tmp1.second.first,tmp1.first.first+tmp2.second.first);    tmp.second.second=min(tmp2.second.second,tmp1.second.second+tmp2.first.first);    tmp.first.second=min(tmp1.first.second,tmp2.first.second);    tmp.first.second=min(tmp.first.second,tmp1.second.second+tmp2.second.first);    return tmp;}int main() {    int n;    while(scanf("%d",&n)==1) {        tolsum=0;        build(0,n-1,1);        int m;        scanf("%d",&m);        while(m--) {            int x,c;            scanf("%d%d",&x,&c);            x--;            update(0,n-1,x,c,1);            tolsum+=c-a[x];            a[x]=c;            printf("%d\n",max(max(query1(0,n-1,0,n-2,1).first.second,query1(0,n-1,1,n-1,1).first.second),tolsum-min(query2(0,n-1,0,n-2,1).first.second,query2(0,n-1,1,n-1,1).first.second)));        }    }    return 0;}


原创粉丝点击