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的更多相关文章

  1. Atcoder Regular Contest 092 D - Two Faced Edges(图论+bitset 优化)

    Atcoder 题面传送门 & 洛谷题面传送门 orz ymx,ymx ddw %%% 首先既然题目要我们判断强连通分量个数是否改变,我们首先就将原图 SCC 缩个点呗,缩完点后我们很自然地将 ...

  2. 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 ...

  3. AtCoder Regular Contest 092 C D E F

    C - 2D Plane 2N Points 题意 二维平面上有\(N\)个红点,\(N\)个蓝点,一个红点和一个蓝点能配成一对当且仅当\(x_r<x_b\)且\(y_r<y_b\). 问 ...

  4. Atcoder Regular Contest 092 A 的改编

    原题地址 题目大意 给定平面上的 $n$ 个点 $p_1, \dots, p_n$ .第 $i$ 点的坐标为 $(x_i, y_i)$ .$x_i$ 各不相同,$y_i$ 也各不相同.若两点 $p_i ...

  5. 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 ...

  6. 思维定势--AtCoder Regular Contest 092 D - Two Sequences

    $n \leq 100000$的俩序列,数字范围$2^{28}$,问所有$a_i+b_j$的$n^2$个数字的异或和. 这种东西肯定是按位考虑嘛,从低位开始然后补上进位.比如说第一位俩串分别有$c$个 ...

  7. 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 ...

  8. 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 ...

  9. 【AtCoder Regular Contest 092】C.2D Plane 2N Points【匈牙利算法】

    C.2D Plane 2N Points 题意:给定N个红点二维坐标N个蓝点二维坐标,如果红点横纵坐标都比蓝点小,那么它们能够构成一组.问最多能构成多少组. 题解:把满足要求的红蓝点连线,然后就是匈牙 ...

随机推荐

  1. poj3411

    Paid Roads Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6549   Accepted: 2427 Descri ...

  2. 将list集合,元素随机打乱

    for循环+随机数 实现相同位置的元素交换 public <T> void shuffle(List<T> list) { int size = list.size(); Ra ...

  3. 转义字符的理解(JAVA、字符串和正则表达式)

    一.原理总结: 要理解转义,首先要从正则表达式说起. 在正则表达式中:*和\是特殊字符:为了匹配这两个字符本身,正则表达式中需要写为\*和\\ 在Java中,只能用字符串表示正则表达式,所以需要把\* ...

  4. 巨蟒python全栈开发-第21天 继承

    一.今日主要内容 1.了解python2和python3类的区别 python2在2.2之前使用的是经典类,2.2之后,使用的是新式类 class Foo: pass class Foo(object ...

  5. Tornado源码浅析

    初识tornado 经典的hello world 案例: import tornado.ioloop import tornado.web class MainHandler(tornado.web. ...

  6. Unix file types

    w https://en.wikipedia.org/wiki/Unix_file_types A socket is a special file used for inter-process co ...

  7. <2014 05 14> Android平台下2D/3D开发攻略

    Android通过OpenGL包含了对高性能2D和3D图形的支持,尤其支持OpenGLES API.OpenGL是一个跨平台的图形API,提供了软件操作3D图形硬件的接口.OpenGLES是一个专用于 ...

  8. ubuntu14 编译安装(升级)g++

    编译安装(升级)g++ ubuntu14自带的g++为4.8.4,不支持c++11.现要将g++升至5.2.0 1.下载安装: 参考https://www.cppfans.org/1719.html ...

  9. 报错:Cannot remove entries from nonexistent file c:\program files\anaconda3\lib\site-packages\easy-install.pth

    Outline 这两天通过“掘金量化终端”跑模型策略,之前装好环境一直ok,可以顺畅的Running~ 下午重装了下 Anaconda,刚才跑的时候提示 缺少“gm”模块 (掘金量化必须包): 就按照 ...

  10. 如何实现redis集群?

    由于Redis出众的性能,其在众多的移动互联网企业中得到广泛的应用.Redis在3.0版本前只支持单实例模式,虽然现在的服务器内存可以到100GB.200GB的规模,但是单实例模式限制了Redis没法 ...