# 2020 hdu多校赛 第八场 1002 Breaking Down News

  1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #include<cstdlib>
7 #include<queue>
8 #include<map>
9 #define N 1000005
10 using namespace std;
11 char xch,xB[1<<15],*xS=xB,*xTT=xB;
12 #define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
13 inline int read()
14 {
15     int x=0,f=1;char ch=getc();
16     while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
18     return x*f;
19 }
20 map<int,int> ma;
21 int T,n,L,R;
22 int A[N];
23 int sum[N];
24 int zz,B[N];
25 struct no{
26     int left,right,mid;
27     int mx;
28 }node[N*4];
29 priority_queue<int> q1[N],q2[N];
30 void build(int left,int right,int x)
31 {
32     node[x].left=left;
33     node[x].right=right;
34     node[x].mx=-1e7;
35     if(left==right)
36     {
37         return;
38     }
39     int mid=(left+right)>>1;
40     node[x].mid=mid;
41     build(left,mid,x<<1);
42     build(mid+1,right,x<<1|1);
43 }
44 int F[N];
45 int get(int left,int right,int x)
46 {
47     if(left>right)return -1e7;
48     if(left==node[x].left&&right==node[x].right)
49     {
50         return node[x].mx;
51     }
52     int mid=node[x].mid;
53     if(left>mid) return get(left,right,x<<1|1);
54     else if(right<=mid)return get(left,right,x<<1);
55     else return max(get(left,mid,x<<1),get(mid+1,right,x<<1|1));
56 }
57 void ch(int to,int x,int da)
58 {
59     if(node[x].left==node[x].right)
60     {
61         node[x].mx=da;
62         return;
63     }
64     int mid=node[x].mid;
65     if(to>mid) ch(to,x<<1|1,da);
66     else ch(to,x<<1,da);
67     node[x].mx=max(node[x<<1].mx,node[x<<1|1].mx);
68 }
69 int main()
70 {
71     T=read();
72     while(T--)
73     {
74         n=read();
75         L=read();
76         R=read();
77         ma.clear();
78         zz=0;
79         for(int i=1;i<=n;i++)
80         {
81             A[i]=read();
82             sum[i]=sum[i-1]+A[i];
83             if(!ma[sum[i]])
84             {
85                 zz++;
86                 B[zz]=sum[i];
87                 ma[sum[i]]=1;
88             }
89             F[i]=0;
90         }
91         if(!ma[0])
92         {
93             zz++;
94             B[zz]=0;
95             ma[0]=1;
96         }
97         sort(B+1,B+zz+1);
98         for(int i=1;i<=zz;i++)
99         {
100             ma[B[i]]=i;
101             while(!q1[i].empty()) q1[i].pop();
102             while(!q2[i].empty()) q2[i].pop();
103         }
104         build(1,zz,1);
105         q1[ma[0]].push(0);
106         ch(ma[0],1,0);
107         for(int i=1;i<=L;i++) F[i]=-1e7;
108         for(register int i=L;i<=n;++i)
109         {
110             F[i]=max(max(get(1,ma[sum[i]]-1,1)+1,get(ma[sum[i]],ma[sum[i]],1)),get(ma[sum[i]]+1,zz,1)-1);
111             if(F[i]>n||F[i]<-n) F[i]=-1e7;
112             if(i-L+1>=0&&F[i-L+1]!=-1e7)
113             {
114                 int tmp=ma[sum[i-L+1]];
115
116                 q1[tmp].push(F[i-L+1]);
117
118                 while(!q1[tmp].empty()&&!q2[tmp].empty()&&q1[tmp].top()==q2[tmp].top()) q1[tmp].pop(),q2[tmp].pop();
119                 ch(tmp,1,q1[tmp].top());
120             }
121             if(i-R>=0&&F[i-R]!=-1e7)
122             {
123                 int tmp=ma[sum[i-R]];
124                 q2[tmp].push(F[i-R]);
125
126                 while(!q1[tmp].empty()&&!q2[tmp].empty()&&q1[tmp].top()==q2[tmp].top()) q1[tmp].pop(),q2[tmp].pop();
127                 if(q1[tmp].empty()) ch(tmp,1,-1e7);
128                 else ch(tmp,1,q1[tmp].top());
129             }
130         }
131         printf("%d\n",F[n]);
132     }
133     return 0;
134 }
135 /*
136 1
137 5 1 1
138 1 -1 0 -1 1
139 */
View Code

posted @ 2020-08-13 21:07  Hzoi_joker  阅读(232)  评论(0编辑  收藏  举报