ARC 085
来源:互联网 发布:中兴手机刷机软件 编辑:程序博客网 时间:2024/06/06 01:54
E
最小割模板题不会做系列。
其实问题就是每个数选择保留或者不保留各有一个花费,然后有nlogn个关系形如:如果i不保留,j也一定不能保留
正数的和为总价值,减去最小割就是答案
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e13using namespace std;const int maxn = 210;const int maxm = 110000;int n,st,ed;int s[maxn];struct edge{int y,nex;ll c;}a[maxm]; int len,fir[maxn];inline void ins(const int x,const int y,const ll c){ a[++len]=(edge){y,fir[x],c};fir[x]=len; a[++len]=(edge){x,fir[y],0};fir[y]=len;}queue<int>q;int h[maxn];bool bfs(){ for(int i=1;i<=ed;i++) h[i]=0; h[st]=1; q.push(st); while(!q.empty()) { const int x=q.front(); q.pop(); for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(a[k].c&&!h[y]) h[y]=h[x]+1,q.push(y); } return h[ed]>0;}ll dfs(const int x,const ll flow){ if(x==ed) return flow; ll delta=0; for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(a[k].c&&h[y]==h[x]+1) { ll mink=dfs(y,min(a[k].c,flow-delta)); a[k].c-=mink; a[k^1].c+=mink; delta+=mink; if(delta==flow) return delta; } if(!delta) h[x]=0; return delta;}ll flow(){ ll re=0; while(bfs()) re+=dfs(st,LLONG_MAX); return re;}ll re;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&s[i]); if(s[i]>0) re+=(ll)s[i]; } len=1; // st=n+1,ed=st+1; for(int i=1;i<=n;i++) { if(s[i]>0) ins(i,ed,(ll)s[i]); if(s[i]<0) ins(st,i,(ll)-s[i]); for(int j=i+i;j<=n;j+=i) ins(i,j,inf); } printf("%lld\n",re-flow()); return 0;}
F
不同的位最少可以转化成相同的位最多(不转直接做也行)
然后位置i,如果bi=1,覆盖他可以得到1的价值,bi=0,覆盖他可以得到-1的价值,问题变成若干个区间,每个区间选或不选,要求选出的区间并集的价值和最大。
将区间放到左端点处理,从1~n枚举左端点,假设当前枚举的左端点是i,设f[r]表示处理了1~i-1的左端点,区间最远覆盖到r的最大价值,线段树优化转移
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e9using namespace std;inline void up(int &x,const int &y){if(x<y)x=y;}const int maxn = 210000;int n,m;int b[maxn],s[maxn],f[maxn];vector<int>V[maxn];int segf[maxn<<2],segd[maxn<<2];void pushup(int seg[],const int x){ seg[x]=seg[x<<1]>seg[x<<1|1]?seg[x<<1]:seg[x<<1|1]; }void build(const int x,const int l,const int r){ if(l==r) { segd[x]=l>=0?-inf:0; return; } int mid=l+r>>1,lc=x<<1,rc=lc|1; build(lc,l,mid); build(rc,mid+1,r); pushup(segd,x);}int lx,rx,loc,c;void upd(int seg[],const int x,const int l,const int r){ if(l==r) { seg[x]=c; return; } int mid=l+r>>1,lc=x<<1,rc=lc|1; if(loc<=mid) upd(seg,lc,l,mid); else upd(seg,rc,mid+1,r); pushup(seg,x);}int query(int seg[],const int x,const int l,const int r){ if(rx<l||r<lx) return -inf; if(lx<=l&&r<=rx) return seg[x]; int mid=l+r>>1,lc=x<<1,rc=lc|1; return max(query(seg,lc,l,mid),query(seg,rc,mid+1,r));}int re;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&b[i]),re+=!b[i]; for(int i=1;i<=n;i++) s[i]=s[i-1]+(b[i]?1:-1); build(1,0,n); for(int i=1;i<=n;i++) f[i]=-inf; scanf("%d",&m); for(int i=1;i<=m;i++) { int l,r; scanf("%d%d",&l,&r); V[l].push_back(r); } for(int i=1;i<=n;i++) { for(int j=0;j<V[i].size();j++) { int r=V[i][j]; lx=0,rx=i-1; int cc=query(segf,1,0,n); up(f[r],cc+s[r]-s[i-1]); lx=i-1,rx=r-1; cc=query(segd,1,0,n); up(f[r],cc+s[r]); loc=r,c=f[r]; upd(segf,1,0,n); c=f[r]-s[r]; upd(segd,1,0,n); } } int ans=0;for(int i=1;i<=n;i++) up(ans,f[i]); printf("%d\n",n-(re+ans)); return 0;}
阅读全文
0 0
- ARC 085
- ARC
- ARC
- arc
- ARC
- ARC
- ARC
- ARC
- arc
- ARC
- ARC
- arc
- arc
- ARC
- arc
- ARC
- ARC
- arc
- 纪念品分组
- PHP面向对象6-常量,Static(静态)关键字
- 打造自己的JavaScript武器库
- 完全数
- SpringMVC Controller介绍及常用注解
- ARC 085
- ajax复习
- 使用开源 phpqrcode 生成二维码
- ZoomImageView实现手势操作图片的单击
- 布局适配的问题解决
- Mongo 排序,多个字段排序
- JSP页面之间传值的方法总结
- JavaScript中字符串的字符串方法
- oracle和mysql数据库的批量update在mybatis中的配置