1.结论题,不会证
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int base=200*500; 4 const int limit=2*200*500; 5 int T,n,a[555]; 6 bitset<205*505*2+5>f,g; 7 inline int get(int ban) 8 { 9 f.reset(); 10 f[0+base]=1; 11 for(int i=1;i<=n;++i) 12 if(i!=ban) 13 { 14 int x=a[i]; 15 g.reset(); 16 g|=f>>x; 17 g|=f<<x; 18 f=g; 19 } 20 int g=0; 21 for(int i=-base;i<=base;++i) 22 if(f[i+base]&&abs(i)<=abs(a[ban])) 23 g=max(g,abs(abs(i)-a[ban])); 24 return g; 25 } 26 bool cmp(int x,int y) 27 { 28 return x>y; 29 } 30 inline void solve() 31 { 32 cin>>n; 33 for(int i=1;i<=n;++i) 34 cin>>a[i]; 35 if(n==1) 36 { 37 cout<<abs(a[1])<<endl; 38 return; 39 } 40 int sum=0; 41 sort(a+1,a+n+1,cmp); 42 for(int i=n;i>=1;--i) 43 if(a[i]<0) 44 sum-=a[i],n=i-1; 45 if(n==0) 46 { 47 cout<<sum<<endl; 48 return; 49 } 50 int ans=0; 51 ans=max(ans,get(1)); 52 cout<<ans+sum<<endl; 53 } 54 int main() 55 { 56 freopen("second.in","r",stdin); 57 freopen("second.out","w",stdout); 58 ios::sync_with_stdio(false); 59 cin>>T; 60 for(int i=1;i<=T;++i) 61 { 62 cout<<"Case #"<<i<<": "; 63 solve(); 64 } 65 return 0; 66 }
2.我点分又写错了!!!maxp又没有归零!!!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=2E4+5; 4 int n,L,R,a[maxn],b[maxn]; 5 int size,head[maxn]; 6 struct edge 7 { 8 int to,next,w; 9 }E[maxn*2]; 10 inline void add(int u,int v,int w) 11 { 12 E[++size].to=v; 13 E[size].next=head[u]; 14 E[size].w=w; 15 head[u]=size; 16 } 17 vector<int>circle,roots; 18 bool isCircle[maxn]; 19 namespace seg 20 { 21 const int inf=10000000; 22 int TOT,t[20000005],root[20000005],ls[20000005],rs[20000005]; 23 void changeT(int l,int r,int pos,int x,int&num) 24 { 25 if(!num) 26 num=++TOT; 27 t[num]=max(t[num],x); 28 if(l==r) 29 return; 30 int mid=(l+r)>>1; 31 if(pos<=mid) 32 changeT(l,mid,pos,x,ls[num]); 33 else 34 changeT(mid+1,r,pos,x,rs[num]); 35 } 36 int askT(int l,int r,int L,int R,int num) 37 { 38 if(!num) 39 return -inf; 40 if(L<=l&&r<=R) 41 return t[num]; 42 int mid=(l+r)>>1; 43 if(R<=mid) 44 return askT(l,mid,L,R,ls[num]); 45 else if(mid<L) 46 return askT(mid+1,r,L,R,rs[num]); 47 return max(askT(l,mid,L,R,ls[num]),askT(mid+1,r,L,R,rs[num])); 48 } 49 inline int newTree() 50 { 51 return ++TOT; 52 } 53 inline void change(int pos,int x,int num) 54 { 55 assert(pos+n>=0); 56 changeT(0,n+n+n+n+n,pos+n+n,x+inf,root[num]); 57 } 58 inline int ask(int L,int R,int num) 59 { 60 return askT(0,n+n+n+n+n,L+n+n,R+n+n,root[num])-inf; 61 } 62 } 63 namespace getCircle 64 { 65 int from[maxn],TI,dfn[maxn]; 66 bool vis[maxn]; 67 void dfs(int u,int F) 68 { 69 dfn[u]=++TI; 70 vis[u]=1; 71 for(int i=head[u];i;i=E[i].next) 72 { 73 int v=E[i].to; 74 if(v==F) 75 continue; 76 if(!vis[v]) 77 { 78 from[v]=u; 79 dfs(v,u); 80 } 81 else if(dfn[v]<dfn[u]) 82 { 83 int p=u; 84 do 85 { 86 circle.push_back(p); 87 p=from[p]; 88 }while(p!=v); 89 circle.push_back(v); 90 } 91 } 92 } 93 void main() 94 { 95 dfs(1,1); 96 if(circle.size()==0) 97 circle.push_back(1); 98 for(int i=0;i<circle.size();++i) 99 isCircle[circle[i]]=1; 100 } 101 } 102 namespace solveTree 103 { 104 int fa[maxn]; 105 void dfs(int u,int F) 106 { 107 fa[u]=F; 108 for(int i=head[u];i;i=E[i].next) 109 { 110 int v=E[i].to; 111 if(v==F) 112 continue; 113 dfs(v,u); 114 } 115 } 116 inline void init() 117 { 118 for(int e=0;e<circle.size();++e) 119 { 120 int u=circle[e]; 121 for(int i=head[u];i;i=E[i].next) 122 { 123 int v=E[i].to; 124 if(!isCircle[v]) 125 { 126 roots.push_back(v); 127 dfs(v,u); 128 } 129 } 130 } 131 } 132 int root,TI,sum[maxn],maxp[maxn],vis[maxn]; 133 int getSum(int u,int F) 134 { 135 sum[u]=1; 136 for(int i=head[u];i;i=E[i].next) 137 { 138 int v=E[i].to; 139 if(v==F||vis[v]==TI||isCircle[v]) 140 continue; 141 sum[u]+=getSum(v,u); 142 } 143 return sum[u]; 144 } 145 void getP(int u,int F,int tot) 146 { 147 maxp[u]=0;// !?!?!?!? 148 for(int i=head[u];i;i=E[i].next) 149 { 150 int v=E[i].to; 151 if(v==F||vis[v]==TI||isCircle[v]) 152 continue; 153 getP(v,u,tot); 154 maxp[u]=max(maxp[u],sum[v]); 155 } 156 maxp[u]=max(maxp[u],tot-sum[u]); 157 if(maxp[u]<maxp[root]) 158 root=u; 159 } 160 void clear(int u,int F) 161 { 162 maxp[u]=0; 163 for(int i=head[u];i;i=E[i].next) 164 { 165 int v=E[i].to; 166 if(v==F) 167 continue; 168 clear(v,u); 169 } 170 } 171 struct pt 172 { 173 int x,y; 174 pt(int a=0,int b=0):x(a),y(b){} 175 }; 176 vector<pt>wait; 177 void getPath(int u,int F,int sx,int sy) 178 { 179 sy+=b[u]; 180 wait.push_back(pt(sx,sy)); 181 for(int i=head[u];i;i=E[i].next) 182 { 183 int v=E[i].to; 184 if(v==F||vis[v]==TI||isCircle[v]) 185 continue; 186 getPath(v,u,sx+E[i].w,sy); 187 } 188 } 189 bool solve(int u,int d=0) 190 { 191 if(L==0&&b[u]>=0) 192 return true; 193 vis[u]=TI; 194 vector<pt>now; 195 int num=seg::newTree(); 196 for(int e=head[u];e;e=E[e].next) 197 { 198 int v=E[e].to; 199 if(isCircle[v]||vis[v]==TI) 200 continue; 201 wait.clear(); 202 getPath(v,u,E[e].w,0); 203 for(int i=0;i<wait.size();++i) 204 if(L<=wait[i].x&&wait[i].x<=R&&wait[i].y+b[u]>=0) 205 return true; 206 207 for(int i=0;i<wait.size();++i) 208 { 209 int x=wait[i].x,y=wait[i].y; 210 if(seg::ask(L-x,R-x,num)>=-y-b[u]) 211 return true; 212 } 213 for(int i=0;i<wait.size();++i) 214 seg::change(wait[i].x,wait[i].y,num); 215 } 216 for(int e=head[u];e;e=E[e].next) 217 { 218 int v=E[e].to; 219 if(isCircle[v]||vis[v]==TI) 220 continue; 221 root=0; 222 getSum(v,u); 223 getP(v,u,sum[v]); 224 if(solve(root,d+1)) 225 return true; 226 } 227 return false; 228 } 229 inline bool checkT() 230 { 231 ++TI; 232 maxp[0]=n+1; 233 for(int i=0;i<roots.size();++i) 234 { 235 int u=roots[i]; 236 clear(u,fa[u]); 237 root=0; 238 int x=getSum(u,fa[u]); 239 getP(u,fa[u],sum[u]); 240 if(solve(root)) 241 return true; 242 } 243 return false; 244 } 245 inline bool checkP() 246 { 247 ++TI; 248 int num1=seg::newTree(),num2=seg::newTree(); 249 int sum=0,tot=0,LEN=circle.size(); 250 for(int q=0;q<circle.size();++q) 251 tot+=b[circle[q]]; 252 for(int q=0;q<circle.size();++q) 253 { 254 int u=circle[q]; 255 vector<pt>now; 256 int num=seg::newTree(); 257 for(int e=head[u];e;e=E[e].next) 258 { 259 int v=E[e].to; 260 if(isCircle[v]) 261 continue; 262 wait.clear(); 263 getPath(v,u,E[e].w,0); 264 265 for(int i=0;i<wait.size();++i) 266 { 267 int x=wait[i].x,y=wait[i].y; 268 if(seg::ask(L-x,R-x,num)>=-y-b[u]) 269 return true; 270 } 271 for(int i=0;i<wait.size();++i) 272 seg::change(wait[i].x,wait[i].y,num); 273 for(int i=0;i<wait.size();++i) 274 now.push_back(wait[i]); 275 } 276 now.push_back(pt(0,0)); 277 278 for(int i=0;i<now.size();++i) 279 if(L<=now[i].x&&now[i].x<=R&&now[i].y+b[u]>=0) 280 return true; 281 282 for(int i=0;i<now.size();++i) 283 { 284 int x=now[i].x,y=now[i].y; 285 if(seg::ask(L-x-q,R-x-q,num1)>=-y-b[u]-sum) 286 return true; 287 } 288 for(int i=0;i<now.size();++i) 289 { 290 int x=now[i].x,y=now[i].y; 291 if(seg::ask(L-x-LEN+q,R-x-LEN+q,num2)>=-y-tot+sum) 292 return true; 293 } 294 295 for(int i=0;i<now.size();++i) 296 seg::change(now[i].x-q,now[i].y-sum,num1); 297 for(int i=0;i<now.size();++i) 298 seg::change(now[i].x+q,now[i].y+sum+b[u],num2); 299 sum+=b[u]; 300 } 301 return false; 302 } 303 } 304 inline void init() 305 { 306 getCircle::main(); 307 solveTree::init(); 308 } 309 inline bool check(int x) 310 { 311 for(int i=1;i<=n;++i) 312 b[i]=(a[i]>=x)?1:-1; 313 if(solveTree::checkT()||solveTree::checkP()) 314 return true; 315 return false; 316 } 317 int main() 318 { 319 freopen("tour20.in","r",stdin); 320 // freopen("tour.out","w",stdout); 321 ios::sync_with_stdio(false); 322 cin>>n>>L>>R; 323 for(int i=1;i<=n;++i) 324 cin>>a[i]; 325 int x,y,z; 326 while((cin>>x>>y>>z)) 327 { 328 if(z==0) 329 z=1; 330 else 331 z=-1; 332 add(x,y,z); 333 add(y,x,z); 334 } 335 init(); 336 int l=0,r=32768,mid; 337 while(l<r) 338 { 339 mid=(l+r+1)>>1; 340 if(check(mid)) 341 l=mid; 342 else 343 r=mid-1; 344 } 345 cout<<l<<endl; 346 // cout<<seg::TOT<<endl; 347 return 0; 348 }