UVA 1400 线段树
input
n m 1<=n,m<=500000
a1 a2 ... an |ai|<=1e9
m行查询
每行一对a b
output
对于每对a b输出区间[a,b]中最小连续和x y,如果有多组满足,输出x最小,如果还有多组满足,输出y最小
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <ctime> 11 #include <cmath> 12 #define MAX 500000 13 14 using namespace std; 15 16 struct pos 17 { 18 int s,e; 19 bool operator<(const pos&a)const 20 { 21 if(s!=a.s) return s<a.s; 22 return e<a.e; 23 } 24 }; 25 struct node 26 { 27 long long sum,suf,pre; 28 int pree,sufs; 29 }; 30 long long sum[MAX*3],pre[MAX*3],sub[MAX*3],suf[MAX*3],maxsum; 31 int n,m,pree[MAX*3],sufs[MAX*3],a,b,cas=1; 32 pos subp[MAX*3],minp; 33 void build(int l,int r,int k) 34 { 35 if(l==r) 36 { 37 scanf("%lld",&sum[k]); 38 pre[k]=suf[k]=sum[k]; 39 pree[k]=sufs[k]=subp[k].s=subp[k].e=l; 40 sub[k]=sum[k]; 41 return; 42 } 43 int m=l+((r-l)>>1),lc=k<<1,rc=(k<<1)+1; 44 build(l,m,lc); 45 build(m+1,r,rc); 46 sum[k]=sum[lc]+sum[rc]; //sum 47 pre[k]=sum[lc]+pre[rc]; //pre 48 pree[k]=pree[rc]; 49 if(pre[k]<=pre[lc]) 50 { 51 pre[k]=pre[lc]; 52 pree[k]=pree[lc]; 53 } 54 suf[k]=suf[lc]+sum[rc]; //suf 55 sufs[k]=sufs[lc]; 56 if(suf[k]<suf[rc]) 57 { 58 sufs[k]=sufs[rc]; 59 suf[k]=suf[rc]; 60 } 61 sub[k]=pre[rc]+suf[lc]; //sub 62 subp[k].s=sufs[lc],subp[k].e=pree[rc]; 63 if(sub[k]<sub[rc]) 64 { 65 sub[k]=sub[rc]; 66 subp[k]=subp[rc]; 67 } 68 else if(sub[k]==sub[rc]) subp[k]=min(subp[k],subp[rc]); 69 if(sub[k]<sub[lc]) 70 { 71 sub[k]=sub[lc]; 72 subp[k]=subp[lc]; 73 } 74 else if(sub[k]==sub[lc]) subp[k]=min(subp[k],subp[lc]); 75 } 76 node query(int l,int r,int k) 77 { 78 if(a<=l&&b>=r) 79 { 80 if(sub[k]>maxsum) 81 { 82 maxsum=sub[k]; 83 minp=subp[k]; 84 } 85 else if(sub[k]==maxsum) minp=min(minp,subp[k]); 86 node u; 87 u.pre=pre[k];u.pree=pree[k];u.sum=sum[k];u.suf=suf[k];u.sufs=sufs[k]; 88 return u; 89 } 90 int m=l+((r-l)>>1),lc=k<<1,rc=(k<<1)+1; 91 node lcc,rcc; 92 if(a<=m) lcc=query(l,m,lc); 93 if(b>m) rcc=query(m+1,r,rc); 94 if(a<=m&&b>m) 95 { 96 node u; 97 u.sum=lcc.sum+rcc.sum; //sum 98 u.pre=lcc.sum+rcc.pre; //pre 99 u.pree=rcc.pree; 100 if(u.pre<=lcc.pre) 101 { 102 u.pre=lcc.pre; 103 u.pree=lcc.pree; 104 } 105 u.suf=lcc.suf+rcc.sum; //suf 106 u.sufs=lcc.sufs; 107 if(u.suf<rcc.suf) 108 { 109 u.sufs=rcc.sufs; 110 u.suf=rcc.suf; 111 } 112 long long subk=rcc.pre+lcc.suf; //sub 113 pos subpk; 114 subpk.s=lcc.sufs,subpk.e=rcc.pree; 115 if(subk>maxsum) 116 { 117 maxsum=subk; 118 minp=subpk; 119 } 120 else if(subk==maxsum) minp=min(minp,subpk); 121 return u; 122 } 123 else if(a<=m) return lcc; 124 else return rcc; 125 } 126 int main() 127 { 128 freopen("/home/user/桌面/in","r",stdin); 129 while(scanf("%d%d",&n,&m)==2) 130 { 131 build(1,n,1); 132 printf("Case %d:\n",cas++); 133 while(m--) 134 { 135 scanf("%d%d",&a,&b); 136 minp.s=minp.e=n; 137 maxsum=-0x7fffffff-1; 138 query(1,n,1); 139 printf("%d %d\n",minp.s,minp.e); 140 } 141 } 142 //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); 143 return 0; 144 }