2020牛客暑期多校训练营(第二场)H Happy Triangle 题解

题意:

实现一个数据结构,支持

1、插入一个整数x

2、删除一个整数x

3、给定一个整数x,问x是否可以和这个数据结构中的两个数组成三角形。

我们可以发现这样一个性质,如果存在解,那么一定有一个解中与x组成三角形的两个数大小相邻。

那么事情就好办了,我们只要维护这个数据结构中大小相邻的两数之差和之和,然后询问x的时候找到之差小于x的数对中和最大的就可以了。

具体实现就是插入和删除的时候用set找前驱后继,将两数之差离散后用堆维护两数之差为X时两数之和的最大值。查找时用线段树查找即可。

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<cstdio>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #define N 200005
 11 using namespace std;
 12 struct Multiset{
 13     multiset<int> s;
 14     int count(int x)
 15     {
 16         return s.count(x);
 17     }
 18     void insert( int x ){
 19         s.insert(x);
 20     }
 21     void earse( int x ){
 22         if( !s.count(x) ) return;
 23         multiset<int>::iterator sit = s.find(x);
 24         if( sit == s.end() ) return;
 25         s.erase(sit);
 26     }
 27     int pre( int x ){
 28         multiset<int>::iterator sit = s.lower_bound(x);
 29         if( sit == s.begin() ) return -1;
 30         sit--;
 31         return *sit;
 32     }
 33     int nxt( int x ){
 34         multiset<int>::iterator sit = s.upper_bound(x);
 35         if( sit == s.end() ) return -1;
 36         return *sit;
 37     }
 38 }s;
 39 int Q;
 40 int F[N][10];
 41 struct no{
 42     int left,right,mid;
 43     int mx;
 44 }node[N*4*3];
 45 priority_queue<int> q1[N*2],q2[N*2];
 46 void build(int left,int right,int x)
 47 {
 48     node[x].left=left;
 49     node[x].right=right;
 50     if(node[x].left==node[x].right)
 51     {
 52         node[x].mx=-1;
 53         return;
 54     }
 55     int mid=(left+right)>>1;
 56     node[x].mid=mid;
 57     build(left,mid,x<<1);
 58     build(mid+1,right,x<<1|1);
 59     node[x].mx=-1;
 60 }
 61 void change(int x,int to,int val)
 62 {
 63     if(node[x].left==node[x].right)
 64     {
 65         node[x].mx=val;
 66         return;
 67     }
 68     int mid=node[x].mid;
 69     if(to>mid) change(x<<1|1,to,val);
 70     else change(x<<1,to,val);
 71     node[x].mx=max(node[x<<1].mx,node[x<<1|1].mx);
 72 }
 73 int get(int to,int x)
 74 {
 75     if(node[x].left==node[x].right)return node[x].mx;
 76     int mid=node[x].mid;
 77     if(to>mid) return max(node[x<<1].mx,get(to,x<<1|1));
 78     else return get(to,x<<1);
 79 }
 80 int cnt,B[N*5];
 81 map<int,int> ma;
 82 int main()
 83 {
 84     scanf("%d",&Q);
 85     for(int i=1;i<=Q;i++)
 86     {
 87         scanf("%d%d",&F[i][0],&F[i][1]);
 88     }
 89     for(int i=1;i<=Q;i++)
 90     {  
 91         if(F[i][0]==1)
 92         {
 93             int pr,fr,sm;
 94             sm=s.count(F[i][1]);
 95             pr=s.pre(F[i][1]);
 96             fr=s.nxt(F[i][1]);
 97             s.insert(F[i][1]);
 98             if(sm)
 99             {
100                 pr=F[i][1];
101             }
102             F[i][2]=pr;
103             F[i][3]=fr;
104             if(pr!=-1)
105             {
106                 if(!ma[F[i][1]-pr])
107                 {
108                     ma[F[i][1]-pr]=1;
109                     cnt++;
110                     B[cnt]=F[i][1]-pr;
111                 }
112             }
113             if(fr!=-1)
114             {
115                 if(!ma[fr-F[i][1]])
116                 {
117                     ma[fr-F[i][1]]=1;
118                     cnt++;
119                     B[cnt]=fr-F[i][1];
120                 }
121             }
122         }
123         else if(F[i][0]==2)
124         {
125             int pr,fr,sm;
126             sm=s.count(F[i][1]);
127             pr=s.pre(F[i][1]);
128             fr=s.nxt(F[i][1]);
129             s.earse(F[i][1]);
130             if(sm>1)
131             {
132                 pr=F[i][1];
133             }
134             F[i][2]=pr;
135             F[i][3]=fr;
136             if(fr!=-1&&pr!=-1)
137             {
138                 if(!ma[fr-pr])
139                 {
140                     ma[fr-pr]=1;
141                     cnt++;
142                     B[cnt]=fr-pr;
143                 }
144             }
145              
146         }
147         else
148         {
149             if(!ma[F[i][1]])
150             {
151                 cnt++;
152                 B[cnt]=F[i][1];
153             }
154         }
155     }
156     sort(B+1,B+cnt+1);
157     for(int i=1;i<=cnt;i++) ma[B[i]]=i;
158     build(1,cnt,1);
159     for(int i=1;i<=Q;i++)
160     {
161         if(F[i][0]==1)
162         {
163             int fr=F[i][3],pr=F[i][2],op;
164             if(fr!=-1&&pr!=-1)
165             {
166                 op=ma[fr-pr];
167                 q2[op].push(fr+pr);
168                 while(!q2[op].empty()&&!q1[op].empty()&&q1[op].top()==q2[op].top()) q1[op].pop(),q2[op].pop();
169                 if(!q1[op].empty()) change(1,op,q1[op].top());
170                 else change(1,op,-1);
171             }
172             if(pr!=-1)
173             {
174                 op=ma[F[i][1]-pr];
175                 q1[op].push(F[i][1]+pr);
176                 while(!q2[op].empty()&&!q1[op].empty()&&q1[op].top()==q2[op].top()) q1[op].pop(),q2[op].pop();
177                 change(1,op,q1[op].top());
178             }
179             if(fr!=-1)
180             {
181                 op=ma[fr-F[i][1]];
182                 q1[op].push(F[i][1]+fr);
183                 while(!q2[op].empty()&&!q1[op].empty()&&q1[op].top()==q2[op].top()) q1[op].pop(),q2[op].pop();
184                 change(1,op,q1[op].top());     
185             }
186         }
187         else if(F[i][0]==2)
188         {
189             int fr=F[i][3],pr=F[i][2],op;
190             if(pr!=-1)
191             {
192                 op=ma[F[i][1]-pr];
193                 q2[op].push(F[i][1]+pr);
194                 while(!q2[op].empty()&&!q1[op].empty()&&q1[op].top()==q2[op].top()) q1[op].pop(),q2[op].pop();
195                 if(!q1[op].empty()) change(1,op,q1[op].top());
196                 else change(1,op,-1);
197             }
198             if(fr!=-1)
199             {
200                 op=ma[fr-F[i][1]];
201                 q2[op].push(F[i][1]+fr);
202                 while(!q2[op].empty()&&!q1[op].empty()&&q1[op].top()==q2[op].top()) q1[op].pop(),q2[op].pop();
203                 if(!q1[op].empty()) change(1,op,q1[op].top());
204                 else change(1,op,-1);
205             }
206             if(fr!=-1&&pr!=-1)
207             {
208                 op=ma[fr-pr];
209                 q1[op].push(fr+pr);
210                 while(!q2[op].empty()&&!q1[op].empty()&&q1[op].top()==q2[op].top()) q1[op].pop(),q2[op].pop();
211                 change(1,op,q1[op].top());
212             }
213         }
214         else
215         {
216             int op=ma[F[i][1]];
217             if(op==1) printf("No\n");
218             else
219             {
220                 long long ans=get(op-1,1);
221                 if(ans>F[i][1]) printf("Yes\n");
222                 else printf("No\n");
223             }
224         }
225     }
226     return 0;
227 }
View Code

 

posted @ 2020-07-14 11:37  Hzoi_joker  阅读(256)  评论(0编辑  收藏  举报