AtCoder Regular Contest 092
AtCoder Regular Contest 092
C - 2D Plane 2N Points
题意:
二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\)类点。每个\(A\)类点可以和横纵坐标都比它大的\(B\)类点匹配,求最大匹配数。
分析:
网络流裸题。
#include <bits/stdc++.h>
using namespace std;
#define MAXN 110
#define inf 0x7fffffff
int head[5+MAXN<<1],dep[5+MAXN<<1],num=-1,s,t,n,m,cur[5+MAXN<<1];
struct po
{
int nxt,to,w;
}edge[MAXN*MAXN*2];
struct point
{
int x,y;
}a[MAXN],b[MAXN];
inline void add_edge(int from,int to,int w)
{
edge[++num].nxt=head[from];
edge[num].to=to;
edge[num].w=w;
head[from]=num;
}
inline void add(int from,int to,int w)
{
add_edge(from,to,w);
add_edge(to,from,0);
}
inline bool bfs()
{
memset(dep,0,sizeof(dep));
queue<int>q;
while(!q.empty()) q.pop();
q.push(s); dep[s]=1;
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].to;
if(edge[i].w&&!dep[v]){
dep[v]=dep[u]+1;
if(v==t) return 1;
q.push(v);
}
}
}
return 0;
}
inline int dfs(int u,int low)
{
if(u==t) return low;
int diss=0;
for(int& i=cur[u];i!=-1;i=edge[i].nxt){
int v=edge[i].to;
if(edge[i].w>0&&dep[v]==dep[u]+1){
int check=dfs(v,min(edge[i].w,low));
if(check){
diss+=check;
low-=check;
edge[i].w-=check;
edge[i^1].w+=check;
if(low==0) break;
}
}
}
return diss;
}
inline int dinic()
{
int ans=0;
while(bfs()){
for(int i=s;i<=t;i++) cur[i]=head[i];
while(int d=dfs(s,inf)) ans+=d;
}
return ans;
}
int main()
{
memset(head,-1,sizeof(head));
cin>>n;s=0,t=2*n+1;
for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y,add(s,i,1);
for(int i=1;i<=n;i++) cin>>b[i].x>>b[i].y,add(i+n,t,1);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) if(a[i].x<b[j].x&&a[i].y<b[j].y) add(i,j+n,1);
cout<<dinic();
}
D - Two Sequences
题意:
给出长度为\(N\)的\(A\)和\(B\)两个数列,求两个数列任意两个数和的异或和。
分析:
可以发现的是,如果两个数\(a,b\)使\(a+b<2^k\)的话,那么他们在\(2^k\)这一位的贡献就是0,如果\(2^{k+1}<a+b<2^{k+1}+2^k\)的话,那么这两个数在\(2^k\)这一位的贡献也为0,对于每一个\(a_i\)二分和在这个范围内的\(b\)。可以得出结果。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=2e5+7;
ll a[MAXN],b[MAXN],B[MAXN],A[MAXN];
int n;
inline ll find(ll k)
{
int l=1,r=n+1;
while(l<r){
int mid=l+r>>1;
if(B[mid]>=k) r=mid;
else l=mid+1;
}
return l;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
ll ans=0;
for(int k=1;k<=29;k++){
ll base=(1<<k)-1;
for(int i=1;i<=n;i++) B[i]=b[i]&base;
for(int i=1;i<=n;i++) A[i]=a[i]&base;
sort(B+1,B+n+1);
ll cnt=0;
for(int i=1;i<=n;i++)
cnt+=n-find((1<<(k-1))-A[i])+1;
for(int i=1;i<=n;i++)
cnt-=find((1<<k)+(1<<(k-1))-A[i])-find((1<<k)-A[i]);
if(cnt&1) ans+=(1<<(k-1));
}
cout<<ans;
}
E - Both Sides Merger
题意:
有一个数列,每个数的绝对值不会超过\(10^9\)。
有两种操作,一种是删去数列两端的其中一个数,另一种是选择一个不是两端的数,将其替换成它两边数的和,并删去那两个数。
求出最终能得到的最大的数和操作方案。
分析:
可以发现我们要么删去两边的一个数,另一个操作本质上不会改变这个数在数列中的奇偶性质。所以记录一下位置在奇数的正数的和和位置在偶数的位置的和比较一下,然后选择一个更大的,输出方案就可以了。
输出方案方法很多,不详述。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=1007;
const int inf=0x3fffffff;
int a[MAXN],n,pre[MAXN],cnt,flag,num,maxx=-inf;
ll ans[MAXN],cnt1,cnt2;
inline bool check_all()
{
for(int i=1;i<=n;i++) if(a[i]>0) return 0;
return 1;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(check_all()){
int l;
for(int i=1;i<=n;i++) if(a[i]>maxx) maxx=a[i],l=i;
cout<<maxx<<endl<<n-1<<endl;
for(int i=n;i>=l+1;i--) cout<<i<<endl;
for(int i=1;i<=l-1;i++) cout<<1<<endl;
return 0;
}
for(int i=1;i<=n;i++){
if(a[i]>0){
if(i&1) cnt1+=a[i];
else cnt2+=a[i];
}
}
if(cnt1>cnt2){
cout<<cnt1<<endl;
flag=1;
} else {
cout<<cnt2<<endl;
flag=2;
}
for(int i=flag;i<=n;i+=2) if(a[i]>0) pre[++cnt]=i;
int now=pre[cnt];
for(int i=n;i>=pre[cnt]+1;i--) ans[++num]=i;
for(int i=cnt-1;i>=1;i--){
int last=now; now=pre[i];
int mid=last+now>>1;
int k=last-now+1;
while(k>1){
ans[++num]=mid;
mid--;
k-=2;
}
}
for(int i=1;i<=pre[1]-1;i++) ans[++num]=1;
cout<<num<<endl;
for(int i=1;i<=num;i++) cout<<ans[i]<<endl;
}
F - Two Faced Edges
题意:
给出一个有向图,询问翻转每一条边是否会对图中的强连通分量产生影响。
分析:
我们可以对每一条边\(u\)-->\(v\)得出两个观察:
1.如果\(v\)已经可以到达\(u\),那么翻转这条边之后会减少一个强连通分量。
2.如果\(u\)可以不通过这条边而到达\(v\),那么翻转之后就会增加一个强连通分量。
对于第一个我们可以暴力bfs预处理出来。
第二个直接暴力找复杂度不对,思考有没有更优秀的算法。
对于每一个点可以拓展出去的点设这些点的集合为\(S\),对于这些点进行编号,然后从每一个点开始bfs,但是不能经过已经遍历过的点。然后将\(S\)翻转,再次进行bfs。两次bfs编号一样的点就是原点没有第二条路径可以到达的点。
这样就可以在时间复杂度内得出结果。
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1007;
struct nod
{
int to,id;
nod(int a,int b)
{
to=a;
id=b;
}
nod(){}
};
int n,m,tim;
int vis[MAXN],can[MAXN][MAXN][2];
int u[MAXN*MAXN],v[MAXN*MAXN];
vector<nod> edge[MAXN];
void dfs(int now,int fa,int b,int f)
{
vis[now]=tim; can[fa][now][f]=b;
for(int i=0;i<edge[now].size();i++){
int v=edge[now][i].to;
if(vis[v]!=tim) dfs(v,fa,b,f);
}
}
inline void solve(int now)
{
tim++; vis[now]=tim;
for(int i=0;i<edge[now].size();i++){
int v=edge[now][i].to;
if(vis[v]!=tim) dfs(edge[now][i].to,now,edge[now][i].id,0);
}
reverse(edge[now].begin(),edge[now].end());
tim++; vis[now]=tim;
for(int i=0;i<edge[now].size();i++){
if(vis[edge[now][i].to]!=tim) dfs(edge[now][i].to,now,edge[now][i].id,1);
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u[i]>>v[i];
edge[u[i]].push_back(nod(v[i],i));
}
for(int i=1;i<=n;i++) solve(i);
for(int i=1;i<=m;i++){
if((can[v[i]][u[i]][0]!=0)^0^(can[u[i]][v[i]][0]!=i||can[u[i]][v[i]][1]!=i))
cout<<("diff\n");
else cout<<("same\n");
}
}
AtCoder Regular Contest 092的更多相关文章
- Atcoder Regular Contest 092 D - Two Faced Edges(图论+bitset 优化)
Atcoder 题面传送门 & 洛谷题面传送门 orz ymx,ymx ddw %%% 首先既然题目要我们判断强连通分量个数是否改变,我们首先就将原图 SCC 缩个点呗,缩完点后我们很自然地将 ...
- AtCoder Regular Contest 092 C - 2D Plane 2N Points(二分图匹配)
Problem Statement On a two-dimensional plane, there are N red points and N blue points. The coordina ...
- AtCoder Regular Contest 092 C D E F
C - 2D Plane 2N Points 题意 二维平面上有\(N\)个红点,\(N\)个蓝点,一个红点和一个蓝点能配成一对当且仅当\(x_r<x_b\)且\(y_r<y_b\). 问 ...
- Atcoder Regular Contest 092 A 的改编
原题地址 题目大意 给定平面上的 $n$ 个点 $p_1, \dots, p_n$ .第 $i$ 点的坐标为 $(x_i, y_i)$ .$x_i$ 各不相同,$y_i$ 也各不相同.若两点 $p_i ...
- AtCoder Regular Contest 092 B Two Sequences
题目大意 给定两个长为 $n$ 个整数序列 $a_1, \dots, a_n$ 和 $b_1, \dots, b_n$ .求所有 $a_i + b_j$($1\le i, j\le n$)的 XOR ...
- 思维定势--AtCoder Regular Contest 092 D - Two Sequences
$n \leq 100000$的俩序列,数字范围$2^{28}$,问所有$a_i+b_j$的$n^2$个数字的异或和. 这种东西肯定是按位考虑嘛,从低位开始然后补上进位.比如说第一位俩串分别有$c$个 ...
- AtCoder Regular Contest 092 Two Sequences AtCoder - 3943 (二进制+二分)
Problem Statement You are given two integer sequences, each of length N: a1,…,aN and b1,…,bN. There ...
- AtCoder Regular Contest 092 2D Plane 2N Points AtCoder - 3942 (匈牙利算法)
Problem Statement On a two-dimensional plane, there are N red points and N blue points. The coordina ...
- 【AtCoder Regular Contest 092】C.2D Plane 2N Points【匈牙利算法】
C.2D Plane 2N Points 题意:给定N个红点二维坐标N个蓝点二维坐标,如果红点横纵坐标都比蓝点小,那么它们能够构成一组.问最多能构成多少组. 题解:把满足要求的红蓝点连线,然后就是匈牙 ...
随机推荐
- 网络通信框架Volley使用详细说明
前一篇粗略的介绍了一下Volley,并在最后附上了一段使用代码,这一篇详细的介绍一下Volley的使用.前面也说了Volley主要获取JSON对象和图片加载,这里也分为两部分介绍. 1.获取JSON对 ...
- java pdf 导出方案
java代码 import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.BaseFont; import org ...
- mysql 数据库备 及移动当天数据到历史表里 window下可用
1 数据移动到历史表中,同时删除当天数据 test-move-record.bat c: cd C:\FQ_ManageServer\mysqlback mysql.exe -h 10.71.1.23 ...
- 1 duilib 自绘标题 最大化图标显示bug ----WindowImplBase的bug
窗口最大化之后有两个问题, 1.最大化按钮的样式还是没变,正确的样式应该是这样的 2.再次点击最大化按钮,不能还原到正常大小. 这个是WindowImplBase的bug,已经 ...
- Converts Internet addresses to Internet numbers. ip2long long2ip
http://php.net/manual/en/function.long2ip.phpPHP: ip2long - Manual http://php.net/manual/en/function ...
- <2014 03 18> Term BreakPoint
- Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
https://www.jb51.net/article/49789.htm 首先说下,由于最新的 0.8 版还是开发版本,因此我使用的是 0.79 版,API 也许会有些不同.因为我是搭配 MySQ ...
- lombok插件使用
1.1 lombok介绍 lombok 是一个可以帮助我们简化java代码编写的工具类,尤其是简化javabean的编写,可以通过采用注解的方式,消除代码中的构造方法,getter/setter等代码 ...
- mongoose学习
#mongoose的使用详解# ##1.Scheme.model和Entity## Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model : 由Schema发布生成 ...
- 转+总结!! 关于jsp页面取值方式
1. 前台往后台传值,通过提交表单,在后台有set,get方法,可以直接取到.如果通过request.getParameter(paramName) 去获取通过会报空指针异常. 其中requ ...