1.sb题。
1 #include<bits/stdc++.h> 2 #define ls son[x][0] 3 #define rs son[x][1] 4 using namespace std; 5 typedef long long int ll; 6 const int maxn=3E5+5; 7 const ll inf=1E12; 8 int n,m; 9 int fa[maxn],son[maxn][2],val[maxn],sum[maxn]; 10 bool tag[maxn]; 11 ll what1[maxn],what2[maxn],cnt1[maxn],cnt2[maxn]; 12 ll tag1[maxn],tag2[maxn]; 13 inline bool notroot(int x) 14 { 15 return son[fa[x]][0]==x||son[fa[x]][1]==x; 16 } 17 inline void put(int x) 18 { 19 tag[x]^=1; 20 swap(son[x][0],son[x][1]); 21 } 22 inline void put1(int x,ll d) 23 { 24 tag1[x]=d; 25 tag2[x]=0; 26 what1[x]=d,what2[x]=-inf,val[x]=d; 27 cnt1[x]=sum[x],cnt2[x]=0; 28 } 29 inline void put2(int x,ll d) 30 { 31 tag2[x]+=d; 32 what1[x]+=d,what2[x]+=d,val[x]+=d; 33 } 34 inline void pushdown(int x) 35 { 36 if(tag[x]) 37 { 38 tag[x]=0; 39 put(ls),put(rs); 40 } 41 if(tag1[x]!=inf) 42 { 43 ll d=tag1[x]; 44 tag1[x]=inf; 45 put1(ls,d),put1(rs,d); 46 } 47 if(tag2[x]) 48 { 49 ll d=tag2[x]; 50 tag2[x]=0; 51 put2(ls,d),put2(rs,d); 52 } 53 } 54 ll tmp[15]; 55 inline bool cmp(ll x,ll y) 56 { 57 return x>y; 58 } 59 inline void pushup(int x) 60 { 61 sum[x]=sum[ls]+sum[rs]+1; 62 what1[0]=what2[0]=-inf;//!!!!!!!!!!!!!!!!!!!!!!!!!!!! 63 cnt1[0]=cnt2[0]=0; 64 tmp[1]=what1[ls],tmp[2]=what2[ls]; 65 tmp[3]=what1[rs],tmp[4]=what2[rs]; 66 tmp[5]=val[x]; 67 sort(tmp+1,tmp+6,cmp); 68 int g=unique(tmp+1,tmp+6)-tmp-1; 69 tmp[g+1]=-inf; 70 what1[x]=tmp[1],what2[x]=tmp[2]; 71 cnt1[x]=cnt2[x]=0; 72 if(what1[x]==what1[ls])cnt1[x]+=cnt1[ls]; 73 if(what1[x]==what2[ls])cnt1[x]+=cnt2[ls]; 74 if(what1[x]==what1[rs])cnt1[x]+=cnt1[rs]; 75 if(what1[x]==what2[rs])cnt1[x]+=cnt2[rs]; 76 if(what1[x]==val[x])cnt1[x]+=1; 77 78 if(what2[x]==what1[ls])cnt2[x]+=cnt1[ls]; 79 if(what2[x]==what2[ls])cnt2[x]+=cnt2[ls]; 80 if(what2[x]==what1[rs])cnt2[x]+=cnt1[rs]; 81 if(what2[x]==what2[rs])cnt2[x]+=cnt2[rs]; 82 if(what2[x]==val[x])cnt2[x]+=1; 83 } 84 void out(int x) 85 { 86 if(!x) 87 return; 88 pushdown(x); 89 out(ls),out(rs); 90 pushup(x); 91 } 92 inline void rotate(int x) 93 { 94 int y=fa[x]; 95 int c=son[y][0]==x; 96 fa[x]=fa[y]; 97 son[y][!c]=son[x][c]; 98 if(son[x][c]) 99 fa[son[x][c]]=y; 100 if(notroot(y)) 101 son[fa[y]][son[fa[y]][1]==y]=x; 102 son[x][c]=y; 103 fa[y]=x; 104 pushup(y); 105 pushup(x); 106 } 107 void down(int x) 108 { 109 if(!notroot(x)) 110 { 111 pushdown(x); 112 return; 113 } 114 down(fa[x]); 115 pushdown(x); 116 } 117 inline void splay(int x) 118 { 119 down(x); 120 while(notroot(x)) 121 { 122 int y=fa[x]; 123 if(!notroot(y)) 124 rotate(x); 125 else if((son[fa[y]][0]==y)==(son[y][0]==x)) 126 rotate(y),rotate(x); 127 else 128 rotate(x),rotate(x); 129 } 130 } 131 inline void access(int x) 132 { 133 splay(x); 134 son[x][1]=0; 135 pushup(x); 136 while(fa[x]) 137 { 138 int y=fa[x]; 139 splay(y); 140 son[y][1]=x; 141 pushup(y); 142 x=y; 143 } 144 splay(x); 145 } 146 inline void makeroot(int x) 147 { 148 access(x); 149 splay(x); 150 put(x); 151 } 152 inline int findroot(int x) 153 { 154 access(x); 155 splay(x); 156 while(son[x][0]) 157 { 158 pushdown(x); 159 x=son[x][0]; 160 } 161 splay(x); 162 return x; 163 } 164 inline void link(int x,int y) 165 { 166 makeroot(x); 167 if(findroot(y)!=x) 168 fa[x]=y; 169 } 170 inline void cut(int x,int y) 171 { 172 makeroot(x); 173 if(findroot(y)==x&&son[x][1]==y) 174 { 175 son[x][1]=fa[y]=0; 176 pushup(x); 177 } 178 } 179 int main() 180 { 181 ios::sync_with_stdio(false); 182 what1[0]=what2[0]=-inf; 183 cnt1[0]=cnt2[0]=1; 184 tag1[0]=inf; 185 cin>>n>>m; 186 for(int i=1;i<=n;++i) 187 { 188 cin>>val[i]; 189 sum[i]=1; 190 what1[i]=val[i],cnt1[i]=1; 191 what2[i]=-inf,cnt2[i]=0; 192 tag1[i]=inf; 193 } 194 for(int i=2;i<=n;++i) 195 { 196 int x,y; 197 cin>>x>>y; 198 link(x,y); 199 } 200 while(m--) 201 { 202 int opt,x,y; 203 cin>>opt>>x>>y; 204 if(opt==1) 205 { 206 int u,v; 207 cin>>u>>v; 208 cut(x,y); 209 link(u,v); 210 } 211 else if(opt==2) 212 { 213 ll d; 214 cin>>d; 215 makeroot(x); 216 access(y); 217 splay(y); 218 put1(y,d); 219 } 220 else if(opt==3) 221 { 222 ll d; 223 cin>>d; 224 makeroot(x); 225 access(y); 226 splay(y); 227 put2(y,d); 228 } 229 else 230 { 231 makeroot(x); 232 access(y); 233 splay(y); 234 ll g=what2[y],d=cnt2[y]; 235 if(g==-inf) 236 cout<<"srO WRS Orz\n"; 237 else 238 cout<<g<<" "<<d<<'\n'; 239 } 240 } 241 return 0; 242 }
2.有一个二分图,将一些点点亮,若一些边两个端点中至少有一个是点亮的那么边会产生额外的贡献;根据点是否被点亮也会产生额外的贡献。问最大贡献。
考虑最小割。注意到“额外贡献”对应的 点对 连边后是一个二分图。若只有两个点,显然我们可以建立出两个三角形形式的边。由于“额外贡献”是两个点产生的,那么它的贡献必然放在中间的一条边上,剩下的就能很轻松的推出。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long int ll; 4 const ll inf=1E9; 5 const int base=12345; 6 const int maxn=1E5+5; 7 int S,T; 8 int dfn[maxn]; 9 struct edge 10 { 11 int to,next; 12 ll w; 13 }E[maxn*2]; 14 int size=1,head[maxn]; 15 inline void addE(int u,int v,ll w) 16 { 17 E[++size].to=v; 18 E[size].next=head[u]; 19 E[size].w=w; 20 head[u]=size; 21 } 22 inline void add(int u,int v,ll w) 23 { 24 addE(u,v,w); 25 addE(v,u,0); 26 } 27 inline bool bfs(int tot) 28 { 29 for(int i=0;i<=tot;++i) 30 dfn[i]=-1; 31 queue<int>Q; 32 Q.push(S); 33 dfn[S]=0; 34 while(!Q.empty()) 35 { 36 int u=Q.front(); 37 Q.pop(); 38 for(int i=head[u];i;i=E[i].next) 39 { 40 int v=E[i].to; 41 if(dfn[v]==-1&&E[i].w) 42 { 43 dfn[v]=dfn[u]+1; 44 Q.push(v); 45 } 46 } 47 } 48 return dfn[T]!=-1; 49 } 50 ll dfs(int u,int up) 51 { 52 if(u==T) 53 return up; 54 ll ans=0; 55 for(int i=head[u];i;i=E[i].next) 56 { 57 int v=E[i].to; 58 if(dfn[v]!=dfn[u]+1||!E[i].w) 59 continue; 60 ll s=dfs(v,min(E[i].w,up-ans)); 61 ans+=s; 62 E[i].w-=s; 63 E[i^1].w+=s; 64 if(s==0) 65 dfn[v]=-1; 66 if(ans==up) 67 break; 68 } 69 return ans; 70 } 71 int n,m,a[maxn],b[maxn]; 72 ll val1[maxn],val2[maxn]; 73 int main() 74 { 75 // freopen("sjy.in","r",stdin); 76 // freopen("sjy.out","w",stdout); 77 ios::sync_with_stdio(false); 78 cin>>n>>m; 79 n=1<<n,m=1<<m; 80 for(int i=0;i<n;++i) 81 cin>>a[i]; 82 for(int i=0;i<n;++i) 83 cin>>b[i]; 84 ll ans=0; 85 for(int i=0;i<n;++i) 86 { 87 for(int j=0;j<m;++j) 88 { 89 ll x; 90 cin>>x; 91 x+=base; 92 if(j<a[i]) 93 val1[i]=max(val1[i],x); 94 else 95 val2[i]=max(val2[i],x); 96 } 97 ans+=val1[i]+val2[i]; 98 } 99 S=0,T=n+1; 100 for(int i=0;i<n;++i) 101 { 102 bool c=__builtin_popcount(i)&1; 103 if(c) 104 add(S,i+1,val1[i]),add(i+1,T,val2[i]); 105 else 106 add(S,i+1,val2[i]),add(i+1,T,val1[i]); 107 for(int j=i+1;j<n;++j) 108 if(__builtin_popcount(i^j)==1) 109 { 110 ll w=b[i]^b[j]; 111 ans+=w; 112 if(c) 113 add(i+1,j+1,w); 114 else 115 add(j+1,i+1,w); 116 } 117 } 118 while(bfs(n+1)) 119 ans-=dfs(S,inf); 120 cout<<ans-(ll)base*n<<endl; 121 return 0; 122 }
3.找到至多m个序列精确覆盖序列[1,2,...,n-1,n]。花费为这((所有序列)的((第一个元素)所在位置)的cost 和(所有序列)(相邻位置间距的)f函数)之和。
注意到操作2的费用只和一个数有关。什么时候用操作2也没有影响。
上下界:这还要说吗?
费用流:每个点要么作为一个序列的终点,要么作为起点,要么作为非终点nor非起点。对于终点,可以使用操作2到达一个序列的起点。因此将一个点拆为上(脑袋)下(尾巴)两部分,源点向尾巴连边,尾巴向脑袋连边,脑袋向汇点连边;对于操作2的部分,源点额外连出m条边,这m条边可以任意使用操作2到达脑袋。进行最小费用最大流即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long int ll; 4 typedef long double ld; 5 const int maxn=1E5+5; 6 const ll inf=1E12; 7 const ld pi=acos(-1); 8 int n,m; 9 struct pt 10 { 11 int x,y,r,p,id; 12 bool operator<(const pt&A)const 13 { 14 return p<A.p; 15 } 16 }a[maxn]; 17 struct info 18 { 19 int u,v; 20 ll l,r,w; 21 }; 22 namespace FLOW 23 { 24 int size,head[maxn]; 25 int S,T; 26 ll dis[maxn]; 27 struct edge 28 { 29 int to,next; 30 ll f,w; 31 }E[maxn*2]; 32 inline void init(int s,int t) 33 { 34 size=1; 35 S=s,T=t; 36 } 37 inline void addE(int u,int v,ll f,ll w) 38 { 39 E[++size].to=v; 40 E[size].f=f; 41 E[size].w=w; 42 E[size].next=head[u]; 43 head[u]=size; 44 } 45 inline void add(int u,int v,ll f,ll w) 46 { 47 assert(S<=u&&u<=T); 48 assert(S<=v&&v<=T); 49 addE(u,v,f,w); 50 addE(v,u,0,-w); 51 } 52 bool vis[maxn]; 53 int pre[maxn]; 54 ll maxF[maxn]; 55 inline bool spfa() 56 { 57 for(int i=S;i<=T;++i) 58 dis[i]=inf,maxF[i]=inf; 59 queue<int>Q; 60 Q.push(S); 61 dis[S]=0; 62 while(!Q.empty()) 63 { 64 int u=Q.front(); 65 Q.pop(); 66 vis[u]=0; 67 for(int i=head[u];i;i=E[i].next) 68 { 69 if(E[i].f==0) 70 continue; 71 int v=E[i].to; 72 ll nw=dis[u]+E[i].w; 73 if(nw<dis[v]) 74 { 75 dis[v]=nw; 76 pre[v]=i; 77 maxF[v]=min(maxF[u],E[i].f); 78 if(!vis[v]) 79 vis[v]=1,Q.push(v); 80 } 81 } 82 } 83 return dis[T]!=inf; 84 } 85 inline ll MCMF() 86 { 87 ll ans=0; 88 while(spfa()) 89 { 90 int pos=T; 91 ll f=maxF[T]; 92 ans+=f*dis[T]; 93 while(pos!=S) 94 { 95 int id=pre[pos]; 96 E[id].f-=f; 97 E[id^1].f+=f; 98 pos=E[id^1].to; 99 } 100 } 101 return ans; 102 } 103 int deg[maxn]; 104 inline int solve(int s,int t,vector<info>Q) 105 { 106 ll sum=0; 107 init(0,t+1); 108 for(int i=0;i<Q.size();++i) 109 { 110 int u=Q[i].u,v=Q[i].v,l=Q[i].l,r=Q[i].r,w=Q[i].w; 111 deg[u]-=l,deg[v]+=l; 112 add(u,v,r-l,w); 113 sum+=(ll)w*l; 114 } 115 for(int i=s;i<=t;++i) 116 { 117 if(deg[i]<0) 118 add(i,T,-deg[i],0); 119 else if(deg[i]>0) 120 add(S,i,deg[i],0); 121 } 122 add(t,s,inf,0); 123 return sum+MCMF(); 124 } 125 } 126 int d[maxn]; 127 inline int numU(int x) 128 { 129 return 3+x; 130 } 131 inline int numD(int x) 132 { 133 return 3+n+2+x; 134 } 135 vector<info>Q; 136 inline ll get(int i,int j) 137 { 138 if(a[i].r>a[j].r) 139 swap(i,j); 140 ll d2=(a[i].x-a[j].x)*(a[i].x-a[j].x)+ 141 (a[i].y-a[j].y)*(a[i].y-a[j].y); 142 ld d=sqrt(d2); 143 ld h=a[j].r-a[i].r; 144 ld ra=asin(h/d); 145 ra=(ra+pi/2)*2; 146 ld la=ra*a[i].r,lb=ra*a[j].r; 147 return (ll)ceil(la*a[i].p+lb*a[j].p+d2); 148 } 149 inline int check() 150 { 151 return true; 152 int d=0,g=0; 153 for(int i=3;i<=n+2;++i) 154 if(a[i].p<a[1].p){++d;break;} 155 for(int i=3;i<=n+2;++i) 156 g=max(g,a[i].p); 157 if(a[2].p<g) 158 ++d; 159 return d; 160 } 161 int main() 162 { 163 // freopen("travel.in","r",stdin); 164 // freopen("travel.out","w",stdout); 165 ios::sync_with_stdio(false); 166 cin>>n>>m; 167 for(int i=1;i<=n+2;++i) 168 { 169 cin>>a[i].x>>a[i].y>>a[i].r>>a[i].p; 170 a[i].id=i; 171 } 172 sort(a+1,a+n+2+1); 173 int S=1,T=numD(n+2)+1; 174 Q.push_back((info){S,3,1,1,0}); 175 Q.push_back((info){2,3,0,m,0}); 176 for(int i=1;i<=n+2;++i) 177 { 178 if(a[i].id==1) 179 Q.push_back((info){3,numU(i),0,1,0}); 180 else 181 Q.push_back((info){3,numU(i),0,1,(ll)ceil(pi*2*a[i].r*a[i].p)}); 182 Q.push_back((info){numU(i),numD(i),1,1,0}); 183 if(a[i].id==2) 184 Q.push_back((info){numD(i),T,1,1,0}); 185 Q.push_back((info){numD(i),2,0,1,0}); 186 } 187 for(int i=1;i<=n+2;++i) 188 for(int j=i+1;j<=n+2;++j) 189 Q.push_back((info){numD(i),numU(j),0,1,get(i,j)}); 190 cout<<"TAK"<<endl; 191 cout<<FLOW::solve(S,T,Q)<<endl; 192 return 0; 193 }
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int u = 233, w = 23333, inf = 0x3f3f3f3f; 8 struct REC{ double x, y; int z; }b[u]; 9 struct rec{ double x, y; }a[u]; 10 double rou[u], rad[u], a1, a2, eps = 1e-12, pi = acos(-1.0); 11 int ver[w], edge[w], cost[w], Next[w], head[u], v[u], q[w * 100], path[u]; 12 int n, m, tot, s, t, l, r, i, x, y, z; 13 long long d[u],ans; 14 15 bool operator <(REC a, REC b) 16 { 17 return a.y + eps<b.y || a.y<b.y + eps&&a.x + eps<b.x; 18 } 19 20 inline double dist(rec a, rec b) 21 { 22 return sqrt((b.x - a.x)*(b.x - a.x) + (b.y - a.y)*(b.y - a.y)); 23 } 24 25 void go(int i, rec ra) 26 { 27 double len = sqrt(ra.x*ra.x + ra.y*ra.y); 28 ra.x = ra.x / len*rad[i]; 29 ra.y = ra.y / len*rad[i]; 30 ra.x += a[i].x, ra.y += a[i].y; 31 b[++m].x = ra.x, b[m].y = ra.y, b[m].z = i; 32 } 33 34 inline rec turn(rec a, double sinth, double costh) 35 { 36 rec b; 37 b.x = a.x*sinth - a.y*costh; 38 b.y = a.x*costh + a.y*sinth; 39 return b; 40 } 41 42 int calc(int i, int j) 43 { 44 cout<<rad[i]<<" "<<rad[j]<<endl; 45 rec rij, ra, rb; 46 double sinth, costh; 47 sinth = (rad[j] - rad[i]) / dist(a[i], a[j]); 48 costh = sqrt(1 - sinth*sinth); 49 double thi = asin(sinth), thj = pi / 2 - thi; 50 thi = (thi + pi / 2) * 2, thj *= 2; 51 cout<<(int)(ceil(rou[i] * rad[i] * thi + rou[j] * rad[j] * thj + dist(a[i], a[j])*dist(a[i], a[j]))+eps)<<endl; 52 return ceil(rou[i] * rad[i] * thi + rou[j] * rad[j] * thj + dist(a[i], a[j])*dist(a[i], a[j]))+eps; 53 /*rij.x = a[j].x - a[i].x; 54 rij.y = a[j].y - a[i].y; 55 ra = turn(rij, sinth, costh); 56 sinth *= -1; 57 rb = turn(rij, sinth, costh); 58 ra = turn(ra, 1, 0); 59 rb = turn(rb, 1, 0); 60 go(i, ra), go(i, rb); 61 go(j, ra), go(j, rb); 62 ra.x *= -1, ra.y *= -1, rb.x *= -1, rb.y *= -1; 63 go(i, ra), go(i, rb); 64 go(j, ra), go(j, rb);*/ 65 } 66 67 void add(int x, int y, int z, int w) 68 { 69 ver[++tot] = y, edge[tot] = z, cost[tot] = w, Next[tot] = head[x], head[x] = tot; 70 ver[++tot] = x, edge[tot] = 0, cost[tot] = -w, Next[tot] = head[y], head[y] = tot; 71 } 72 73 bool spfa() 74 { 75 memset(d, 0x3f, sizeof(d)); 76 memset(v, 0, sizeof(v)); 77 q[l = r = 1] = s, d[s] = 0, v[s] = 1; 78 while (l <= r) 79 { 80 x = q[l++], v[x] = 0; 81 for (i = head[x]; i; i = Next[i]) 82 if (edge[i] && d[y = ver[i]]>d[x] + cost[i]) 83 { 84 d[y] = d[x] + cost[i], path[y] = i; 85 if (!v[y]) q[++r] = y, v[y] = 1; 86 } 87 } 88 if (d[t] == 0x3f3f3f3f3f3f3f3fll) return 0; else return 1; 89 } 90 91 void update() 92 { 93 for (y = t; y != s; y = x) 94 { 95 i = path[y], x = ver[i ^ 1]; 96 edge[i]--, edge[i ^ 1]++; 97 } 98 ans += d[t]; 99 n--; 100 } 101 102 int main() 103 { 104 // freopen("travel.in","r",stdin); 105 // freopen("travel.out","w",stdout); 106 cin >> n >> m; 107 n += 2; 108 s = 2 * n + 1, t = 2 * n + 2, tot = 1; 109 add(s, 0, m, 0); 110 for (i = 1; i <= n; i++) 111 { 112 cin >> a[i].x >> a[i].y >> rad[i] >> rou[i]; 113 if (i == 1) add(s, n + i, 1, 0); 114 else add(0, n + i, 1, (int)(ceil(2 * pi * rad[i] * rou[i]) + eps)); 115 add(s, i, 1, 0); 116 add(n + i, t, 1, 0); 117 } 118 for(int i=1;i<=n;i++) 119 for(int j=1;j<=n;j++) 120 if (i != j&&rou[i] < rou[j] && i != 2 && j != 1) 121 { 122 cout<<i<<" "<<j<<" "<<n<<" "; 123 add(i, n + j, 1, calc(i, j)); 124 } 125 while (spfa()) update(); 126 if (n) puts("Nie"); else puts("TAK"), cout << ans << endl; 127 return 0; 128 }