A题:我们可以发现,ai+aj的最大值为2e5,显然这其中只有sqrt(2e5)个完全平方数。那么我们只需要枚举这个范围内的完全平方数 x,统计有多 少 ai + aj = x。这显然可以一边扫,一边用一个数组来统计。
//
// main.cpp
// wzazzy
//
// Created by apple on 2018/10/23.
// Copyright © 2018年 apple. All rights reserved.
//
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string.h>
#include<queue>
#include<stack>
#include<list>
#include<map>
#include<set>
#include<bitset>
#include<vector>
using namespace std;
typedef long long int ll;
const int maxn =200000+5;
const int maxm=10000;
const int mod =1e9+7;
const int INF=0x3f3f3f3f;
//**********************************
int x;int a[maxn];
int main()
{
int n;scanf("%d",&n);ll ans=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
for(int j=1;j*j<=2E5;j++)
if(j*j>=x) ans+=a[j*j-x];
a[x]++;
}
printf("%lld\n",ans);
return 0;
}
B题:
首先可以知道,如果一张图是二分图最优的染色方案是黑白染色,否则 需要 3 种颜色。
那么只需要判断这张图是否是二分图即可,判断方式就是寻找有没有奇 环。
//
// main.cpp
// wzazzy
//
// Created by apple on 2018/10/23.
// Copyright © 2018年 apple. All rights reserved.
//
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<list>
#include<map>
#include<set>
#include<vector>
using namespace std;
const int maxn = 2e5;
struct edge{int to,isb,rev;};//isb标记桥,rev记录反向边
int n,m;
vector<edge> G[maxn];
int color[maxn],dfs_clock,pre[maxn],low[maxn],vis[maxn],iscut[maxn];
void add_edge(int a,int b)
{
edge u,v;
u.to = b,u.isb = 0,v.to = a,v.isb = 0,u.rev = G[b].size(),v.rev = G[a].size();
G[a].push_back(u);
G[b].push_back(v);
}
bool bipartite(int u)
{
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i].to;
if(!color[v])
{
color[v] = 3 - color[u];
if(!bipartite(v))
return false;
}else if(color[v] == color[u])
return false;
}
return true;
}
int dfs(int u,int fa)
{
int lowu = pre[u] = ++dfs_clock;
int child = 0;
for(int i = 0; i < G[u].size();i++)
{
int v = G[u][i].to;
if(!pre[v])
{
child++;
int lowv = dfs(v,u);
lowu = min(lowu,lowv);
if(lowv > pre[u])
{
G[u][i].isb = 1;
G[v][G[u][i].rev].isb = 1;
// printf("%d -> %d\n",u,v);
}
}else if(pre[v] < pre[u] && v!=fa)
lowu = min(lowu,pre[v]);
}
if(fa < 0 && child == 1) iscut[u] = 0;
low[u] = lowu;
return lowu;
}
int ncnt,mcnt;
void dfs2(int u)
{
// printf("u = %d fa = %d\n",u,fa);
for(int i = 0; i < G[u].size();i++)
{
if(G[u][i].isb)continue;
int v = G[u][i].to;
//printf("%d--%d\n",u,v);
mcnt++;
// printf("%d -> %d\n",u,v);
if(!vis[v])
{
ncnt++;
vis[v] = true;
dfs2(v);
}
}
}
int main()
{
bool odd = false;
scanf("%d%d",&n,&m);
for(int i = 1; i <= n ;i++)
G[i].clear();
memset(color,0,sizeof(color));
memset(pre,0,sizeof(pre));
memset(vis,false,sizeof(vis));
dfs_clock = 0;
for(int i = 0; i < m ;i ++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
}
for(int i =1; i <= n; i++)
if(!color[i])
{
color[i] = 1;
if(!bipartite(i))
odd = true;
}
if(odd)
printf("3");
else
printf("2");
return 0;
}