1. 程式人生 > 實用技巧 >2020牛客暑期多校訓練營(第二場)H Happy Triangle 題解

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