Codeforces 题目传送门 & 洛谷题目传送门

真·ycx 做啥题我就做啥题

考虑枚举 \(j\),我们预处理出 \(c1_i\) 表示与 \(i\) 相连的编号 \(<i\) 的点的个数,再预处理出 \(c2_i\) 表示与 \(i\) 相连的编号 \(>i\) 的个数,那么共有 \(j-c1_j\) 个 \(<j\) 的数可以成为 \(i\),有 \(n-1-c2_j\) 个数可以成为 \(k\),贡献就随便算一下就行了。

但是这样会多算,多算的部分就是 \(i,k\) 有边相连,但 \((i,j),(k,j)\) 均无边相连的部分。考虑另外减去这一部分的贡献,这一次我们枚举有边相连的 \((i,k)\)——显然这一部分复杂度是 \(\mathcal O(m)\) 的,并且钦定 \(i<k\),那么显然对于所有多算的 \(j\),必然有 \((i,j),(k,j)\) 均无边,我们记这样符合要求的 \(j\) 有 \(c\) 个,它们的和为 \(s\),那么多算的贡献就是 \(cAi+cCk+sB\),减一下就行了。

不过到这里有一个问题,那就是符合条件的 \(j\) 无法直接计算,因为这里的 \((i,k)\) 不独立,要是能拆开来计算就好了,可这里拆不掉。考虑有个东西叫做正难则反,我们考虑拿所有符合要求的 \(j\) 减去 \((i,j),(k,j)\) 至少一个有边的 \(j\) 即可。不过到这里问题又来了,那就是这东西还是不好维护,继续考虑容斥原理,这东西又等价于 \((i,j)\) 有边的 \(j\) \(+\) \((k,j)\) 有边的 \(j\),扣掉 \((i,j),(k,j)\) 都有边的 \(j\),而前面这两个东西恰好是可以分开来算的,相当于我们要分别求对于固定的 \(i,k\),满足 \((i,j)\) 之间存在边,并且 \(i<j<k\) 的 \(j\) 的个数及和;以及 \((k,j)\) 之间存在边,并且 \(i<j<k\) 的 \(j\) 的个数及和——拿前一部分举例,我们对于每个 \(i\) 建一个 std::vector<int> \(g2_i\),维护所有 \(j>i,(i,j)\) 之间有边的 \(j\) 并将其排个序,再建另一个 std::vector<int> \(s2_i\) 维护 \(g2_i\) 的前缀和,然后在 \(g2_i\) 中 std::lower_bound 找出 \(k\) 的位置,查遍前缀和即可。

最后考虑 \((i,j),(k,j),(i,k)\) 都有边的 \(i,j,k\) 的贡献,这是一个非常经典的问题,叫「三元环计数」。然鹅 wtcl 在做这题之前还不会这个科技,所以感谢这个题让我学会了这玩意儿。考虑对原图中每条边重新定向,对于无向边 \((u,v)\),只从度数小的连向度数大的边,如果度数相同比编号,显然这样形成一个偏序集,于是每一个三元环 \((i,j,k)\) 与每一个满足 \(i\to j,j\to k,i\to k\) 的边都存在的三元组 \((i,j,k)\) 形成双射,我们就非常暴力地枚举 \(i\),再枚举它的出边 \(j\),再枚举它的出边 \(k\),并检验 \(i\to k\) 的边是否存在即可。容易证明这样复杂度是 \(m\sqrt m\) 的。

总之这题就是一堆正难则反,思维难度倒不算太大

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=2e5;
int n,m,deg[MAXN+5];u64 a,b,c;
u64 sum(u64 l,u64 r){return (l+r)*(r-l+1)/2ull;}
vector<int> g1[MAXN+5],g2[MAXN+5],g[MAXN+5];
vector<u64> s1[MAXN+5],s2[MAXN+5];
int vis[MAXN+5];
int main(){
scanf("%d%d%llu%llu%llu",&n,&m,&a,&b,&c);
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);if(u>v) u^=v^=u^=v;
g1[v].pb(u);g2[u].pb(v);deg[u]++;deg[v]++;
}
u64 ans=0;
for(int i=0;i<n;i++){
sort(g1[i].begin(),g1[i].end());
s1[i].resize(g1[i].size());
for(int j=0;j<g1[i].size();j++){
if(j==0) s1[i][j]=g1[i][j];
else s1[i][j]=s1[i][j-1]+g1[i][j];
}
sort(g2[i].begin(),g2[i].end());
s2[i].resize(g2[i].size());
for(int j=0;j<g2[i].size();j++){
if(j==0) s2[i][j]=g2[i][j];
else s2[i][j]=s2[i][j-1]+g2[i][j];
}
}
for(int i=0;i<n;i++){
u64 cnt1=i-g1[i].size(),cnt2=n-i-1-g2[i].size();
u64 sum1=sum(0,i-1)-((g1[i].empty())?0:s1[i].back());
u64 sum2=sum(i+1,n-1)-((g2[i].empty())?0:s2[i].back());
ans+=cnt1*cnt2*i*b+cnt1*sum2*c+cnt2*sum1*a;
}
for(int i=0;i<n;i++) for(int j:g2[i]){
int pos1=lower_bound(g1[j].begin(),g1[j].end(),i)-g1[j].begin();
int pos2=lower_bound(g2[i].begin(),g2[i].end(),j)-g2[i].begin();
u64 cnt=g1[j].size()-1-pos1+pos2;
u64 rem=j-i-1-cnt;
u64 s=sum(i+1,j-1)-s1[j].back()+s1[j][pos1]-((!pos2)?0:s2[i][pos2-1]);
// printf("%d %d %d %d\n",i,j,rem,s);
ans-=s*b+rem*i*a+rem*j*c;
}
for(int i=0;i<n;i++) for(int j=0;j<g1[i].size();j++){
int x=g1[i][j];
if(deg[i]<deg[x]) g[i].pb(x);
else g[x].pb(i);
} memset(vis,-1,sizeof(vis));
for(int i=0;i<n;i++){
for(int j:g[i]) vis[j]=i;
for(int j:g[i]) for(int k:g[j]){
if(vis[k]==i){
// printf("%d %d %d\n",i,j,k);
u64 tmp[3]={0};tmp[0]=i;tmp[1]=j;tmp[2]=k;
sort(tmp,tmp+3);ans-=tmp[0]*a+tmp[1]*b+tmp[2]*c;
}
}
}
printf("%llu\n",ans);
return 0;
}

Codeforces 985G - Team Players(三元环)的更多相关文章

  1. Codeforces 985G. Team Players

    Description 有 \(n\) 个人 , \(m\) 对人有冲突 , 你要从这 \(n\) 个人中选出三个人成为一组 , 使得同一组的人不存在一对有冲突 题面 Solution 容斥 答案=总 ...

  2. BZOJ.5407.girls/CF985G. Team Players(三元环计数+容斥)

    题面 传送门(bzoj) 传送门(CF) \(llx\)身边妹子成群,这天他需要从\(n\)个妹子中挑出\(3\)个出去浪,但是妹子之间会有冲突,表现为\(i,j\)之间连有一条边\((i,j)\), ...

  3. Codeforces Gym 100342J Problem J. Triatrip 求三元环的数量 bitset

    Problem J. Triatrip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/at ...

  4. Codeforces Gym 100342J Problem J. Triatrip 三元环

    题目链接: http://codeforces.com/gym/100342 题意: 求三元环的个数 题解: 用bitset分别统计每个点的出度的边和入度的边. 枚举每一条边(a,b),计算以b为出度 ...

  5. Codeforces Gym 100342J Problem J. Triatrip bitset 求三元环的数量

    Problem J. TriatripTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/att ...

  6. Codeforces 434E - Furukawa Nagisa's Tree(三元环+点分治)

    Codeforces 题面传送门 & 洛谷题面传送门 场号 hopping,刚好是我的学号(指 round 的编号) 注:下文中分别用 \(X,Y,K\) 代替题目中的 \(x,y,k\) 注 ...

  7. BZOJ.5407.girls(容斥 三元环)

    题目链接 CF 原题 \(Description\) 有n个点,其中有m条边连接两个点.每一个没有连边的三元组\((i,j,k)(i<j<k)\)对答案的贡献为\(A*i+B*j+C*k\ ...

  8. BZOJ 3498 PA2009 Cakes(三元环处理)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3498 [题目大意] N个点m条边,每个点有一个点权a. 对于任意一个三元环(j,j,k ...

  9. HDU 6184 Counting Stars 经典三元环计数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6184 题意: n个点m条边的无向图,问有多少个A-structure 其中A-structure满足V ...

随机推荐

  1. 远程设备管理opendx平台搭建-appium和adb的安装

    多年不见了,说起来也有3年了我又开始写博客了,这几年我还是没啥长进,还是干测试,但是测试行业的话,我已经成了一个测开了,也在搭建自己的测试网站 本系列文章讲述的是一个系列的第一部分,最终可以搭建一整套 ...

  2. 【死磕 NIO】— Reactor 模式就一定意味着高性能吗?

    大家好,我是大明哥,我又来了. 为什么是 Reactor 一般所有的网络服务,一般分为如下几个步骤: 读请求(read request) 读解析(read decode) 处理程序(process s ...

  3. Coursera Deep Learning笔记 序列模型(二)NLP & Word Embeddings(自然语言处理与词嵌入)

    参考 1. Word Representation 之前介绍用词汇表表示单词,使用one-hot 向量表示词,缺点:它使每个词孤立起来,使得算法对相关词的泛化能力不强. 从上图可以看出相似的单词分布距 ...

  4. Beta阶段初始任务分配

    项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-计划-Beta阶段说明书 一.Beta阶段总体规划 根据用户反馈与测试结果修复alpha版本的bu ...

  5. Scrum Meeting 0509

    零.说明 日期:2021-5-9 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 qsy PM&前端 测试 测试 cyy ...

  6. [Beta]the Agiles Scrum Meeting 6

    会议时间:2020.5.20 21:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 issue yjy 帮助成员解决配置环境问题 tq 增加功能:添加多个评测机 评测部分增加更多评测指标 ...

  7. DP接口中AUX

    背景技术: DP接口(DisplayPort)是一种图像显示接口,它不仅可以支持全高清显示分辨率(1920×1080),还能支持4k分辨率(3840×2160),以及最新的8k分辨率(7680×432 ...

  8. CSP-S 2021 退役记

    写的比较草率,但的确是真实感受. 10.23 回寝室前敲了一个 dinic 板子,觉得不会考... 10.24 8:00 起床,还好今天宿管不在,可以起的晚一点. 吃了早饭来机房颓废. 10:00 似 ...

  9. web性能检测工具lighthouse

    About Automated auditing, performance metrics, and best practices for the web. Lighthouse 可以自动检查Web页 ...

  10. 顺时针打印矩阵 牛客网 剑指Offer

    顺时针打印矩阵 牛客网 剑指Offer 题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 ...