[COGS755]山海经

很远古的一道题,当时打的跟(*机房和谐*)一样,后来用$ O(q*n) $的算法卡到了T75

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<cstring>
 6 #define ll long long
 7 #define m(a) memset(a,0,sizeof(a))
 8 using namespace std;
 9 const int maxn=1e5+100;
10 int ans,x,y,w,n,m,a[maxn],l,r,z;
11 int main()
12 {
13     scanf("%d%d",&n,&m);
14     for(register int i=1;i<=n;i++) scanf("%d",&a[i]);
15     for(register int i=1;i<=m;++i)
16     {
17         scanf("%d%d",&x,&y);
18         l=r=w=0;
19         ans=-1e5;
20         z=x;
21         for(register int j=x;j<=y;++j)
22         {
23             w+=a[j];
24             if(w>ans)
25             {
26                 ans=w;
27                 l=z;
28                 r=j;
29             }
30             if(w<0) 
31             {
32                 z=j+1;
33                 w=0;
34             }
35         }
36         printf("%d %d %d\n",l,r,ans);
37     }
38     return 0;
39 }
TLE75

现在打起来这个题是真的简单(虽然我早在4月份已经颓了题解)

首先维护4个w,3个x,3个y,分别代表:

(尖括号代表从哪里转移过来)

(0):左段最大值以及其左右端点

1>w[ls][0]

2>w[ls][3]+w[rs][0]

(1):中间最大值以及其左右端点

1>w[ls][1]

2>w[rs][1]

3>w[ls][2]+w[rs][0]

(2):右段最大值以及其左右端点

1>w[rs][2]

2>w[rs][3]+w[ls][2]

(3):整段的最大值。

1>w[ls][3]+w[rs][3]

因为要输出最小字典序,所以某些最大值相等的情况要考虑字典序的问题

否则会WA88(可能WA0?)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e5+10;
  4 int n,m,f[N];
  5 struct Tree{int l,r,x[3],y[3],w[4];}a[N*4];
  6 int read()
  7 {
  8         int sum,k=1;char s;
  9         while(s=getchar(),s<'0'||s>'9')if(s=='-')k=-1;sum=s-'0';
 10         while(s=getchar(),s>='0'&&s<='9') sum=sum*10+s-'0';
 11         return k*sum;
 12 }
 13 void merge(int k,Tree ls,Tree rs)
 14 {
 15         if(ls.w[0]>=ls.w[3]+rs.w[0])
 16         {
 17                 a[k].w[0]=ls.w[0];
 18                 a[k].x[0]=ls.x[0];
 19                 a[k].y[0]=ls.y[0];
 20         }
 21         else
 22         {
 23                 a[k].w[0]=ls.w[3]+rs.w[0];
 24                 a[k].x[0]=ls.x[0];
 25                 a[k].y[0]=rs.y[0];
 26         }
 27         if(ls.w[2]+rs.w[0]>ls.w[1]||(ls.w[2]+rs.w[0]==ls.w[1]&&ls.x[2]<ls.x[1]))
 28         {
 29                 if(ls.w[2]+rs.w[0]>=rs.w[1])
 30                 {
 31                         a[k].w[1]=ls.w[2]+rs.w[0];
 32                         a[k].x[1]=ls.x[2];
 33                         a[k].y[1]=rs.y[0];
 34                 }
 35                 else
 36                 {
 37                         a[k].w[1]=rs.w[1];
 38                         a[k].x[1]=rs.x[1];
 39                         a[k].y[1]=rs.y[1];
 40                 }
 41         }
 42         else
 43         {
 44                 if(ls.w[1]>=rs.w[1])
 45                 {
 46                         a[k].w[1]=ls.w[1];
 47                         a[k].x[1]=ls.x[1];
 48                         a[k].y[1]=ls.y[1];
 49                 }
 50                 else
 51                 {
 52                         a[k].w[1]=rs.w[1];
 53                         a[k].x[1]=rs.x[1];
 54                         a[k].y[1]=rs.y[1];
 55                 }
 56         }
 57         if(ls.w[2]+rs.w[3]>=rs.w[2])
 58         {
 59                 a[k].w[2]=ls.w[2]+rs.w[3];
 60                 a[k].x[2]=ls.x[2];
 61                 a[k].y[2]=rs.y[3];
 62         }
 63         else
 64         {
 65                 a[k].w[2]=rs.w[2];
 66                 a[k].x[2]=rs.x[2];
 67                 a[k].y[2]=rs.y[2];
 68         }
 69         a[k].w[3]=ls.w[3]+rs.w[3];
 70 }
 71 void build(int k,int l,int r)
 72 {
 73         a[k].l=l;a[k].r=r;
 74         if(l==r)
 75         {
 76                 a[k].x[0]=a[k].x[1]=a[k].x[2]=l;
 77                 a[k].y[0]=a[k].y[1]=a[k].y[2]=l;
 78                 a[k].w[0]=a[k].w[1]=a[k].w[2]=a[k].w[3]=f[l];
 79                 return;
 80         }
 81         int mid=(l+r)>>1;
 82         build(k<<1,l,mid);
 83         build(k<<1|1,mid+1,r);
 84         merge(k,a[k<<1],a[k<<1|1]);
 85 }
 86 Tree query(int k,int l,int r)
 87 {
 88         if(a[k].l>=l&&a[k].r<=r) return a[k];
 89         int mid=(a[k].l+a[k].r)>>1;
 90         Tree X,Y;
 91         if(l<=mid) X=query(k<<1,l,r);
 92         if(r>mid) Y=query(k<<1|1,l,r);
 93         if(l<=mid&&r>mid)
 94         {
 95                 merge(0,X,Y);
 96                 return a[0];
 97         }
 98         else if(l<=mid) return X;
 99         else return Y;
100 }
101 signed main()
102 {
103         //freopen("1.in","r",stdin);
104         //freopen("1.out","w",stdout);
105         n=read();m=read();
106         for(int i=1;i<=n;i++) f[i]=read();
107         build(1,1,n);
108         for(int i=1,x,y,ans,l,r;i<=m;i++)
109         {
110                 x=read();y=read();
111                 Tree S=query(1,x,y);
112                 ans=max(S.w[0],max(S.w[1],S.w[2]));
113                 if(S.w[0]>=S.w[1])
114                 {
115                         if(S.w[0]>=S.w[2]) l=S.x[0],r=S.y[0];
116                         else l=S.x[2],r=S.y[2];
117                 }
118                 else
119                 {
120                         if(S.w[1]>=S.w[2]) l=S.x[1],r=S.y[1];
121                         else l=S.x[2],r=S.y[2];
122                 }
123                 printf("%d %d %d\n",l,r,ans);
124         }
125         return 0;
126 }
AC

 

posted @ 2019-08-22 20:14  ATHOSD  阅读(115)  评论(0编辑  收藏  举报