CS R23 C(排列循环节+前缀和),D(好题,列式子,取交集), E(套路,二分图,最大独立集,最小割)
来源:互联网 发布:js设置颜色渐变 编辑:程序博客网 时间:2024/05/21 10:55
题意:平面上n个点,任意两点距离为其曼哈顿距离,n个点中有些点是特殊的.特殊点间的有快速通道为距离T.
Q次询问:A->B的最短距离.Q,n<=1e3.
建图? 不用阿,两点之间直线最短,所以A->B要么为dis(a,b),
要么走快速通道 暴力枚举一个离a最近的特殊点即可 O(n^2).
#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<int,int> ii;const int N=2e5+20,inf=0x3f3f3f3f;int n,T,q;struct node{int s,x,y;}a[N];int main(){cin>>n>>T;for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i].s,&a[i].x,&a[i].y);cin>>q;while(q--){int s,t;scanf("%d%d",&s,&t);int dis=abs(a[s].x-a[t].x)+abs(a[s].y-a[t].y);int d1=inf,d2=inf;for(int i=1;i<=n;i++){if(a[i].s==0)continue;int t1=abs(a[s].x-a[i].x)+abs(a[s].y-a[i].y);int t2=abs(a[t].x-a[i].x)+abs(a[t].y-a[i].y);d1=min(d1,t1);d2=min(d2,t2);}int ans=min(dis,d1+d2+T);cout<<ans<<endl;}return 0;}Problem C:
题意:给出长度为m的排列a. 现在排列a会生成一个矩阵b
矩阵b:
第一行为 a[1],a[2]..a[j]..a[m].
第二行为 a[a[1]],a[a[2]]..a[a[j]]..a[a[m]].
...
第i行元素为 ..a[a[a[a[..a[j]]..总共套有i个a
n,m<=1e5. 求矩阵中每列元素之和.
看第j列 a[j],a[a[j]]...
找到a[j]所在循环节的长度,记录每个循环节的和,每个元素在自己循环节中的位置(用前缀和算n%size部分),O(N+M)
#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<int,int> ii;const int N=2e5+20;int n,m,a[N],vis[N],bel[N],sum[N],pos[N];vector<int> v[N],pre[N];int main(){int cnt=0;scanf("%d%d",&m,&n);for(int i=1;i<=m;i++)scanf("%d",&a[i]);for(int i=1;i<=m;i++){if(vis[i])continue;int cur=i;++cnt;while(!vis[cur]){v[cnt].push_back(cur);bel[cur]=cnt,sum[cnt]+=a[cur],pos[cur]=v[cnt].size();vis[cur]=1;cur=a[cur];}}for(int i=1;i<=cnt;i++){pre[i]=v[i];for(int j=0;j<v[i].size();j++)pre[i].push_back(v[i][j]);for(int j=1;j<pre[i].size();j++)pre[i][j]=pre[i][j-1]+pre[i][j];}//cout<<cnt<<endl;for(int i=1;i<=m;i++){ll num=bel[i];ll time=n/v[num].size();ll re=n%v[num].size();ll res=pre[num][pos[i]+re-1]-pre[num][pos[i]-1];//a[i]ºóÃære¸öÖ®ºÍ? ¸´ÖÆÒ»±é ÀûÓÃǰ׺ºÍÀ´Çó. printf("%lld ",time*sum[num]+res);}printf("\n");return 0;}Problem D
题意:数轴上n个圆心x[i],第i个圆心的可选半径为[a[i],b[i]].
n<=1e5,a[i],b[i],x[i]<=1e9.问相邻圆都相切时 选择半径的方案数?
第一个点的半径确认了 其余的也就固定了 可是第一个点半径范围r[1]最坏在1e9左右.
r[1]有单调性,?? 若y=r[1]不可行 则y要么是太大 要么是太小了. 二分m时 无法判定m过大还是过小.
d[i]设为(x[i+1],x[i])之间距离
当第一个半径r[1]为x时
r[2]=d1-x;
r[3]=d2-r[2]=d2-d1+x
r[4]=d3-r[3]=d3-d2+d1+x.
..
r[i]=d[i]-d[i-1]+d[i-2]-....((-1)^(i+1)%2 )*x
a[2]<=r[2]<=b[2]
d[1]-b[2]<=x<=d[1]-a[2]
..
因为r[i]是在某个范围(a[i],b[i])内的,d[i]又是常数.
上面每个等式都可以确定x某一段范围,则可行的方案必须在这些区间的交集上,方法数为交集的大小
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e5+20,inf=0x3f3f3f3f;ll n,x[N],a[N],b[N];int main(){cin>>n;for(int i=1;i<=n;i++)scanf("%lld",&x[i]);for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i],&b[i]);ll l=a[1],r=b[1];ll sum=0;for(int i=2;i<=n;i++){sum*=-1;sum+=(x[i]-x[i-1]);if(i%2){l=max(l,a[i]-sum);r=min(r,b[i]-sum);}else{l=max(l,sum-b[i]);r=min(r,sum-a[i]);}}cout<<max(0ll,r-l+1)<<endl;return 0;}
Problem E:
题意:给出n个不同的数,操作:删除任意一个数.
当n个数中任意两个相加都不为prime时,最小需要的操作次数?,并输出删除的点.n<=2000,a[i]<=1e5.
当a[i]+a[j]为prime时 a[i]-a[j]一条边,删除数最小也就是剩下元素最多,求出该图的最大独立集就好了.
奇数和偶数分成两部分,只有奇数到偶数才有可能有边,该图还是个二分图.
最大独立集=总的点数-最小点覆盖.
最小点覆盖:令(u,v)容量为inf,则求最小割时(s,u),(v,t)至少一条在最小割上,满足最小点覆盖要求.
求出最小割后 从s开始dfs一遍 标记到达的点 就能知道那些边是满流边了;(不能到p1则s-p1为满流,能到p2说明p2->t必须为满流)
满流的边不一定是割边!!!!
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e5+20,inf=0x3f3f3f3f,MAXN=5e5;int vis[N],s,t,p1,p2,ans,cnt;int n,a[N];vector<int> odd,even;void table(){for(int i=2;i<N;i++){if(!vis[i])for(int j=i+i;j<N;j+=i)vis[j]=1;}}struct edge{ int from,to,cap,flow; }; struct Dinic{ int n,m,s,t; int vis[MAXN]; int d[MAXN]; int cur[MAXN]; vector<int> G[MAXN]; vector<edge> edges; void init(int n){ this->n=n; for(int i=0;i<n;++i)G[i].clear(); edges.clear(); } void adde(int from,int to,int cap){ edges.push_back(edge{from,to,cap,0}); edges.push_back(edge{to,from,0,0}); int m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS(){ memset(vis,0,sizeof(vis)); vis[s]=1; d[s]=0; queue<int> q; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=0;i<G[x].size();++i){ edge& e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow){ d[e.to]=d[x]+1; vis[e.to]=1; q.push(e.to); } } } return vis[t]; } int DFS(int x,int a){ if(x==t||a==0)return a; int flow=0,f; for(int &i=cur[x];i<G[x].size();++i){ edge& e=edges[G[x][i]]; if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0)break; } } return flow; } int Maxflow(int s,int t){ this->s=s,this->t=t; int flow=0; while(BFS()){ memset(cur,0,sizeof(cur)); flow+=DFS(s,inf); } return flow; }void dfs(int u){vis[u]=1;for(int i=0;i<G[u].size();i++){edge e=edges[G[u][i]];if(!vis[e.to]&&e.flow<e.cap)dfs(e.to);}} }g; int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);table();for(int i=1;i<=n;i++){if(a[i]%2)odd.push_back(a[i]);elseeven.push_back(a[i]);}p1=odd.size(),p2=even.size();s=p1+p2,t=s+1;g.init(t+1); for(int i=0;i<odd.size();i++)g.adde(s,i,1);for(int i=0;i<even.size();i++)g.adde(i+p1,t,1); for(int i=0;i<odd.size();i++) for(int j=0;j<even.size();j++) if(!vis[odd[i]+even[j]]) g.adde(i,p1+j,inf); printf("%d\n",ans=g.Maxflow(s,t)); memset(g.vis,0,sizeof(g.vis));g.dfs(s);for(int i=0;i<p1;i++)if(!g.vis[i])printf("%d ",odd[i]);for(int i=0;i<p2;i++)if(g.vis[i+p1])printf("%d ",even[i]);printf("\n");return 0;}
- CS R23 C(排列循环节+前缀和),D(好题,列式子,取交集), E(套路,二分图,最大独立集,最小割)
- CS R25 C(BFS+二维前缀和) D(好题,合理枚举+树状数组维护) E(建图,连通分量,割点)
- CS R19 C(套路,二分or two pointer). D(构造,相邻位不同,字典最小),E(???)
- [网络流24题] 09 方格取数问题 (二分图点权最大独立集,最小割)
- 【网络流二十四题 方格取数问题】【二分图点权最大独立集->最小割】
- CS R20 C(贪心+二分) D(套路(n后第k个合法数)二分+数位DP.) E(好题:回文,字符串哈希)
- CS R46 C(思维套路),D(好题,数据结构维护) E(???)
- CS R14 C(模拟+二维前缀和) ,D(好题,前缀第i位异或+滑动区间),E(树计数+DP(前缀和优化))
- [网络流24题] 24 骑士共存(二分图最大独立集,网络最小割)
- HDU 1569 二分图带权最大独立集 最小割
- 【网络流24题】方格取数(二分图染色+最大权独立点集+最小割)
- loj6226「网络流 24 题」骑士共存问题(二分图最大点独立集,最小割)
- 【网络流二十四题 骑士共存问题】【二分图点权最大独立集->最小割】
- hdu 1569 &1565 二分图带权最大独立集,最大流最小割定理
- loj6007「网络流 24 题」方格取数(最大点权独立集+最小割)
- Codeforces 808F 网络流最小割(二分图最大点权独立集) 解题报告
- hdu 1565 方格取数(1)(最小割,最大点权独立集)
- hdoj 1569 方格取数(2) 【最小割】 【最大点权独立集】
- 用CXF中wsdl2java工具时抛出SAXParseException
- centos 安装matlab2017a(无root权限)
- 数组去重的方法
- 欢迎使用CSDN-markdown编辑器
- 访问网站人数统计
- CS R23 C(排列循环节+前缀和),D(好题,列式子,取交集), E(套路,二分图,最大独立集,最小割)
- Elasticsearch学习笔记
- Spark任务提交jar包依赖解决方案
- ucos-iii学习之消息传递
- 高德地图开发(一)显示地图与定位
- OpenCV2编程手册笔记之 7.5提取连通区域轮廓
- 2017年互联网带给我什么?
- 客户端连接redis出现:redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running
- Windows下安装Ubuntu 16.04双系统(准备装,先收藏这个博客,写的不错)