首页 > 其他 > 详细

保序回归,贪心,总结

时间:2021-03-03 22:28:20      阅读:51      评论:0      收藏:0      [点我收藏+]

例题:

例题4(我连不上topcoder!)(还没对拍)

技术分享图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long int ll;
  4 typedef pair<int,int> pii;
  5 namespace FLOW
  6 {
  7     const ll inf=1E15; 
  8     int S,T;
  9     int size=1,head[1000005];
 10     struct edge
 11     {
 12         int to,next;
 13         ll w;
 14     }E[1000005];
 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 void init(int s,int t)
 28     {
 29         for(int i=2;i<=size;++i)
 30         {
 31             head[E[i].to]=0;
 32             E[i].to=E[i].w=E[i].next=0;
 33         }
 34         size=1; 
 35         S=s,T=t;
 36     }
 37     int dfn[1000005];
 38     inline bool bfs()
 39     {
 40         for(int i=S;i<=T;++i)
 41             dfn[i]=-1;
 42         queue<int>Q;
 43         dfn[S]=0;
 44         Q.push(S);
 45         while(!Q.empty())
 46         {
 47             int u=Q.front();
 48             Q.pop();
 49             for(int i=head[u];i;i=E[i].next)
 50             {
 51                 int v=E[i].to;
 52                 if(dfn[v]!=-1||E[i].w==0)
 53                     continue;
 54                 dfn[v]=dfn[u]+1;
 55                 Q.push(v);
 56             }
 57         }
 58         return dfn[T]!=-1;
 59     }
 60     ll dfs(int u,ll up)
 61     {
 62         if(u==T)
 63             return up;
 64         ll s=0;
 65         for(int i=head[u];i;i=E[i].next)
 66         {
 67             int v=E[i].to;
 68             if(dfn[v]!=dfn[u]+1||E[i].w==0)
 69                 continue;
 70             ll x=dfs(v,min(up-s,E[i].w));
 71             s+=x;
 72             E[i].w-=x;
 73             E[i^1].w+=x;
 74             if(x==0)
 75                 dfn[v]=-1;
 76             if(s==up)
 77                 break;
 78         }
 79         return s;
 80     }
 81     bool vis[1000005];
 82     vector<int>solve(vector<ll>V,vector<pii>EE)
 83     {
 84         init(0,V.size()+1);
 85 //        cout<<"FLOW "<<S<<" "<<T<<endl;
 86         for(int i=0;i<V.size();++i)
 87         {
 88             ll x=V[i];
 89 //            cout<<"?? "<<i+1<<" "<<x<<endl;
 90             if(x>0)
 91                 add(S,i+1,x);
 92             else
 93                 add(i+1,T,-x);
 94         }
 95         for(int i=0;i<EE.size();++i)
 96         {
 97 //            cout<<"ADD "<<EE[i].first<<" "<<EE[i].second<<endl;
 98             add(EE[i].first,EE[i].second,inf);
 99         }
100         while(bfs())
101             dfs(S,inf);
102         for(int i=S;i<=T;++i)
103             vis[i]=0;
104         queue<int>Q;
105         Q.push(S);
106         vis[S]=1;
107         while(!Q.empty())
108         {
109             int u=Q.front();
110             Q.pop();
111             for(int i=head[u];i;i=E[i].next)
112             {
113                 int v=E[i].to;
114                 if(E[i].w==0||vis[v])
115                     continue;
116                 Q.push(v); 
117                 vis[v]=1;
118             }
119         }
120         vector<int>D;
121         for(int i=head[S];i;i=E[i].next)
122             if(!vis[E[i].to])
123                 D.push_back(E[i].to);
124 //        for(int i=S;i<=T;++i)
125 //            cout<<vis[i]<<" ";cout<<endl;
126         for(int i=head[T];i;i=E[i].next)
127             if(!vis[E[i].to])
128                 D.push_back(E[i].to);
129         sort(D.begin(),D.end());
130         return D;
131     }
132 }
133 int n,m;
134 struct pt
135 {
136     int x,y;
137     ll d,w;
138 }a[1005];
139 bool yes[1005][1005];
140 vector<int>E[1005],what[1005];
141 vector<int>wait;
142 void dfs1(int u,int F,int s)
143 {
144     for(int i=1;i<=m;++i)
145         if(min(a[i].x,a[i].y)==min(u,s)&&max(a[i].x,a[i].y)==max(u,s))
146             for(int j=0;j<wait.size();++j)
147                 yes[wait[j]][i]=1;
148     for(int i=0;i<E[u].size();++i)
149     {
150         int v=E[u][i];
151         if(v==F)
152             continue;
153         wait.push_back(what[u][i]);
154         dfs1(v,u,s);
155         wait.pop_back();
156     }
157 }
158 inline void init1()
159 {
160     for(int i=1;i<=n;++i)
161         dfs1(i,0,i);
162 }
163 void dfs2(int u,int F,int s)
164 {
165     for(int i=1;i<=m;++i)
166         if(min(a[i].x,a[i].y)==min(u,s)&&max(a[i].x,a[i].y)==max(u,s))
167             for(int j=0;j<wait.size();++j)
168                 yes[i][wait[j]]=1;
169     for(int i=0;i<E[u].size();++i)
170     {
171         int v=E[u][i];
172         if(v==F)
173             continue;
174         wait.push_back(what[u][i]);
175         dfs2(v,u,s);
176         wait.pop_back();
177     }
178 }
179 inline void init2()
180 {
181     for(int i=1;i<=n;++i)
182         dfs2(i,0,i);
183 }
184 int ans[1005];
185 void solve(vector<int>V,vector<int>D)
186 {
187     if(V.empty())
188         return;
189     if(D.size()==1)
190     {
191         for(int i=0;i<V.size();++i)
192             ans[V[i]]=D[0];
193         return;
194     }
195     assert(D.size()!=0);
196     int mid=(D.size()-1)/2;
197     ll x=D[mid],y=D[mid+1];
198     vector<ll>V2;
199     vector<pii>E;
200     for(int i=0;i<V.size();++i)
201         for(int j=0;j<V.size();++j)
202             if(yes[V[i]][V[j]])
203                 E.push_back(pii(i+1,j+1));
204     for(int i=0;i<V.size();++i)
205     {
206 //        cout<<"?!?! "<<V[i]<<" "<<x<<" "<<y<<" "<<a[V[i]].d<<" "<<a[V[i]].w<<endl; 
207         V2.push_back(-(abs(a[V[i]].d-y)-abs(a[V[i]].d-x))*a[V[i]].w);
208     }
209     vector<int>D2=FLOW::solve(V2,E);
210 //    cout<<"NOW"<<endl;
211 //    for(auto p:V)
212 //        cout<<p<<" ";cout<<endl;
213 //    for(auto p:D)
214 //        cout<<p<<" ";cout<<endl;
215 //    for(auto p:D2)
216 //        cout<<p<<" ";cout<<endl;
217 //    system("pause");
218     vector<int>VL,VR,DL,DR;
219     int pos=0;
220     for(int i=0;i<V.size();++i)
221     {
222         if(pos!=D2.size()&&D2[pos]==V[i])
223         {
224             VL.push_back(V[i]);
225             ++pos; 
226         }
227         else
228             VR.push_back(V[i]);
229     }
230     for(int i=0;i<=mid;++i)
231         DL.push_back(D[i]);
232     for(int i=mid+1;i<D.size();++i)
233         DR.push_back(D[i]);
234     solve(VL,DL),solve(VR,DR);
235 }
236 int main()
237 {
238     ios::sync_with_stdio(false);
239     cin>>n>>m;
240     vector<int>V,D;
241     for(int i=1;i<=m;++i)
242     {
243         cin>>a[i].x>>a[i].y>>a[i].d>>a[i].w;
244         V.push_back(i);
245         D.push_back(a[i].d);
246     }
247     sort(D.begin(),D.end());
248     unique(D.begin(),D.end());
249     for(int i=2;i<=n;++i)
250     {
251         int x;
252         cin>>x;
253         E[a[x].x].push_back(a[x].y);
254         what[a[x].x].push_back(x);
255         E[a[x].y].push_back(a[x].x);
256         what[a[x].y].push_back(x);
257     }
258     init1();
259     for(int i=1;i<=n;++i)
260         E[i].clear(),what[i].clear();
261     for(int i=2;i<=n;++i)
262     {
263         int x;
264         cin>>x;
265         E[a[x].x].push_back(a[x].y);
266         what[a[x].x].push_back(x);
267         E[a[x].y].push_back(a[x].x);
268         what[a[x].y].push_back(x);
269     }
270     init2();
271 //    for(int i=1;i<=m;++i,cout<<endl)
272 //        for(int j=1;j<=m;++j)
273 //            cout<<yes[i][j]<<" ";cout<<endl; 
274     solve(V,D);
275     ll sum=0;
276     for(int i=1;i<=m;++i)
277         sum+=abs(ans[i]-a[i].d)*a[i].w;
278     cout<<sum<<endl;
279     for(int i=1;i<=m;++i)
280         cout<<ans[i]<<endl; 
281     return 0;
282 }
View Code

 


 

[USACO21JAN铂金] Minimum Cost Paths(luoguP7294)

我们形式化地计算一条路径的代价。我们记录第i列走到了第$s_i$行,那么走到(n,m)的总代价就是$\sum_{i=1}^{m-1}{(s_i-s_{i-1})*a_i+s_i^2}+(n-s_{m-1})*a_m$(计算相邻两列行数增加产生的贡献,以及除了最后一列列数增加产生的贡献),其中$s_0=1$,且$s_i\leqs_{i+1}$。

 

注意到$(s_i-\frac{a_{i+1}-a_i}{2})^2=s_i^2-s_i*a_{i+1}+s_i*a_i+(\frac{a_{i+1}-a_i}{2})^2$,令$c_i=\frac{a_{i+1}-a_i}{2}$,需要优化的式子变为:

 

$\sum_{i=1}^{m-1}{(s_i-c_i)^2}+C$(注意上标!),其中$C$是一个我们不需要关心的常数。至此,这变成了L2问题。

 

注意到问题特殊的拓扑关系,我们可以沿用论文中的例题1的方法。由于s得是整数,最后所有的s都四舍五入(并且这是正确的)。由于多组询问,我们得保证s小于等于每次询问的x,而m等于每次询问的y,因此我们离线将询问按照y从小到大排序依次处理,对于每次询问二分到栈上相应的位置计算相应的贡献即可。

 

注意s也是正整数!

技术分享图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long int ll;
  4 typedef long double ld;
  5 const int maxn=2E5+5;
  6 ll n,m,q,ans[maxn];
  7 ld a[maxn],c[maxn],sumA[maxn];
  8 int tot;
  9 ld f[maxn],s[maxn];
 10 int L[maxn],R[maxn];
 11 struct query
 12 {
 13     int id,x,y;
 14     bool operator<(const query&A)const
 15     {
 16         return y<A.y;
 17     }
 18 }Q[maxn];
 19 namespace BIT
 20 {
 21     ll t[maxn];
 22     inline int lowbit(int x)
 23     {
 24         return x&(-x);
 25     }
 26     inline ll ask(int x)
 27     {
 28         ll s=0;
 29         while(x)
 30         {
 31             s+=t[x];
 32             x-=lowbit(x);
 33         }
 34         return s;
 35     }
 36     inline void add(int x,ll y)
 37     {
 38         while(x<=m)
 39         {
 40             t[x]+=y;
 41             x+=lowbit(x);
 42         }
 43     }
 44 }
 45 inline void push(ld x,ld y,int l,int r)
 46 {
 47     f[++tot]=x;
 48     s[tot]=y;
 49     L[tot]=l;
 50     R[tot]=r;
 51 }
 52 ll now=0;
 53 inline ll get(int pos)
 54 {
 55     ll x=round(max((ld)1,f[pos]));
 56     ll y=round(max((ld)1,f[pos-1]));
 57     return (x-y)*a[L[pos]]+x*x*(R[pos]-L[pos]+1);
 58 }
 59 inline void update()
 60 {
 61     while(tot>=2&&f[tot-1]>f[tot])
 62     {
 63         ld x=(s[tot-1]*f[tot-1]+s[tot]*f[tot])/(s[tot-1]+s[tot]),y=s[tot-1]+s[tot];
 64         int l=L[tot-1],r=R[tot];
 65         ld g=get(tot);
 66         now-=g;
 67         BIT::add(tot,-g);
 68         
 69         g=get(tot-1);
 70         now-=g;
 71         BIT::add(tot-1,-g);
 72         
 73         tot-=2; 
 74         push(x,y,l,r);
 75         g=get(tot);
 76         now+=g;
 77         BIT::add(tot,g);
 78     }
 79 }
 80 int b[maxn];
 81 int tmp[maxn];
 82 inline ll solve(ll x,ll y)
 83 {
 84     if(y==1)
 85         return (x-1)*a[1];
 86     int l=1,r=tot,mid;
 87     while(l<r)
 88     {
 89         mid=(l+r)>>1;
 90         if(f[mid]<=x)
 91             l=mid+1;
 92         else
 93             r=mid;
 94     }
 95     mid=l;
 96     ll sum=BIT::ask(mid-1);
 97     ll X=max((ll)1,(ll)round(min((ld)x,f[mid])));
 98     ll Y=max((ll)1,(ll)round(min((ld)x,f[mid-1])));
 99     sum+=a[L[mid]]*X-a[L[mid]]*Y+X*X*(y-1-L[mid]+1);
100     return sum+(x-X)*a[y];
101     /*
102     for(int i=1;i<=tot;++i)
103         for(int j=L[i];j<=R[i];++j)
104             b[j]=min((int)round(max((ld)1,f[i])),x);
105     ll sum=0;
106     for(int i=1;i<=y-1;++i)
107         sum+=(ll)(b[i]-b[i-1])*a[i]+(ll)b[i]*b[i];
108     return sum+(ll)(x-b[y-1])*a[y];
109     */
110 }
111 inline void solve()
112 {
113     f[0]=1;
114     sort(Q+1,Q+q+1);
115     int pos=1;
116     for(int i=1;i<=m-1;++i)
117     {
118         while(pos<=q&&Q[pos].y==i)
119         {
120             ans[Q[pos].id]=solve(Q[pos].x,Q[pos].y);
121             ++pos;
122         }
123         push(c[i],1,i,i);
124         ld g=get(tot); 
125         now+=g;
126         BIT::add(tot,g);
127         update();
128     }
129     while(pos<=q)
130     {
131         ans[Q[pos].id]=solve(Q[pos].x,Q[pos].y);
132         ++pos;
133     }
134 }
135 int main()
136 {
137 //    freopen("a.in","r",stdin);
138 //    freopen("a.out","w",stdout);
139     ios::sync_with_stdio(false);
140     cin>>n>>m;
141     for(int i=1;i<=m;++i)
142     { 
143         cin>>a[i];
144         sumA[i]=sumA[i-1]+a[i];
145     }
146     for(int i=1;i<m;++i)
147         c[i]=(a[i+1]-a[i])/2;
148     cin>>q;
149     for(int i=1;i<=q;++i)
150     {
151         cin>>Q[i].x>>Q[i].y;
152         Q[i].id=i;
153     }
154     solve();
155     for(int i=1;i<=q;++i)
156         cout<<ans[i]<<\n;
157     return 0;
158 }
View Code

 

保序回归,贪心,总结

原文:https://www.cnblogs.com/GreenDuck/p/14476886.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!