持续菜炸
本着一血拿卫衣的想法,我开始了这场挑战赛
众所周知T1一般是水题,于是我早已做好了准备
看到T1,给定两个数组,自行决定顺序,使
∑
m
a
x
{
b
i
−
a
i
,
0
}
\sum max\{b_i-a_i,0\}
∑max{bi−ai,0}最大
一眼贪心,排序计算即可,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
#include<cctype>
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;int n,a[100010],b[100010];
LL ans;
inline LL read()
{
char c;LL d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
signed main()
{
n=read();
for(register int i=1;i<=n;i++) a[i]=read();
for(register int i=1;i<=n;i++) b[i]=read();
sort(a+1,a+1+n);sort(b+1,b+1+n);
for(register int i=1;i<=n;i++) ans+=max(0,b[n-i+1]-a[i]);
printf("%lld",ans);
}
于是我的码题手速得到极致发挥,可惜。。。
终究慢了30秒。。。
失去了卫衣的我心灰意冷,加之AJ鸡汤罚时,早已失去信心
T2是给定一张无向图,求边变点,点边变重复无穷次后点的数量
肛了好久的规律,这里直接放出来
- 若存在度>3的点,必然发散
- 若一个连通子图恰好是一个大小为 k k k的链,则这个连通子图变化 k k k次后必然变成没有贡献的分量
- 若一个连通子图恰好是一个大小为 k k k的环,则这个连通子图的贡献即为 k k k
- 特判恰好有一个度为3的点的情况
- 非上述2,3,4情况的,必然发散
求完每个点的度之后遍历每个子图即可,时间复杂度 O ( n + m ) O(n+m) O(n+m)
T i p s Tips Tips(附:判断一个联通子图正好为链或正好为环的办法)
设 b l o blo blo表示这个连通子图的大小(点数)
- 当入度恰好为2的有 b l o − 2 blo-2 blo−2个,入度为1的恰好有2个时,这是链,贡献为0
- 当入度恰好为2的有 b l o blo blo个时,这是环,贡献为 b l o blo blo
- 在第二点的基础上,如果此时 b l o blo blo的大小大于3,则该连通子图最终一定发散, b r e a k break break
- 至于入度恰好为3,判断 b l o blo blo是否正好4个(即菊花图),是的话贡献为3,否则没有贡献
#include<cctype>
#include<cstdio>
#define LL long long
#define N 100010
using namespace std;int n,m,x,y,tot,l[N],vis[N],rd1,rd2,rd3,ans,blo,rd[N];
struct node{int next,to;}e[N<<1];
inline void add(int u,int v){e[++tot]=(node){l[u],v};l[u]=tot;return;}
inline LL read()
{
char c;LL d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void dfs(int x,int col)
{
vis[x]=col;blo++;
if(rd[x]==1) rd1++;
if(rd[x]==2) rd2++;
if(rd[x]==3) rd3++;
for(register int i=l[x];i;i=e[i].next)
{
int y=e[i].to;
if(vis[y]) continue;
dfs(y,col);
}
return;
}
signed main()
{
n=read();m=read();
for(register int i=1;i<=m;i++)
{
x=read();y=read();
add(x,y);add(y,x);
rd[x]++;rd[y]++;
}
for(register int i=1;i<=n;i++) if(rd[i]>3) return puts("-1")&0;
for(register int i=1;i<=n;i++)
{
if(vis[i]) continue;
rd1=0;rd2=0;blo=0;rd3=0;
dfs(i,i);
if(rd1==2&&rd2==blo-2) continue;
if(rd3)
{
if(blo==4) ans+=3;
else return puts("-1")&0;
}
if(rd2==blo) ans+=blo;
else if(rd2&&blo>3) return puts("-1")&0;
}
printf("%d",ans);
}