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 }
View Code

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 }
View Code

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 }
View Code
  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 }
View Code

 

 posted on 2020-09-10 15:49  GreenDuck  阅读(174)  评论(0编辑  收藏  举报