Codeforces 985G - Team Players(三元环)
真·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(三元环)的更多相关文章
- Codeforces 985G. Team Players
Description 有 \(n\) 个人 , \(m\) 对人有冲突 , 你要从这 \(n\) 个人中选出三个人成为一组 , 使得同一组的人不存在一对有冲突 题面 Solution 容斥 答案=总 ...
- BZOJ.5407.girls/CF985G. Team Players(三元环计数+容斥)
题面 传送门(bzoj) 传送门(CF) \(llx\)身边妹子成群,这天他需要从\(n\)个妹子中挑出\(3\)个出去浪,但是妹子之间会有冲突,表现为\(i,j\)之间连有一条边\((i,j)\), ...
- Codeforces Gym 100342J Problem J. Triatrip 求三元环的数量 bitset
Problem J. Triatrip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/at ...
- Codeforces Gym 100342J Problem J. Triatrip 三元环
题目链接: http://codeforces.com/gym/100342 题意: 求三元环的个数 题解: 用bitset分别统计每个点的出度的边和入度的边. 枚举每一条边(a,b),计算以b为出度 ...
- Codeforces Gym 100342J Problem J. Triatrip bitset 求三元环的数量
Problem J. TriatripTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/att ...
- Codeforces 434E - Furukawa Nagisa's Tree(三元环+点分治)
Codeforces 题面传送门 & 洛谷题面传送门 场号 hopping,刚好是我的学号(指 round 的编号) 注:下文中分别用 \(X,Y,K\) 代替题目中的 \(x,y,k\) 注 ...
- BZOJ.5407.girls(容斥 三元环)
题目链接 CF 原题 \(Description\) 有n个点,其中有m条边连接两个点.每一个没有连边的三元组\((i,j,k)(i<j<k)\)对答案的贡献为\(A*i+B*j+C*k\ ...
- BZOJ 3498 PA2009 Cakes(三元环处理)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3498 [题目大意] N个点m条边,每个点有一个点权a. 对于任意一个三元环(j,j,k ...
- HDU 6184 Counting Stars 经典三元环计数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6184 题意: n个点m条边的无向图,问有多少个A-structure 其中A-structure满足V ...
随机推荐
- 耗时一个月,整理出这份Hadoop吐血宝典
本文目录: 一.HDFS 二.MapReduce 三.Yarn 四.Hadoop3.x 新特性 五.Hadoop 大厂面试真题解析 Hadoop 涉及的知识点如下图所示,本文将逐一讲解: 本文档参考了 ...
- Hadoop面试题(四)——YARN
1.简述hadoop1与hadoop2 的架构异同 1)加入了yarn解决了资源调度的问题. 2)加入了对zookeeper的支持实现比较可靠的高可用. 2.为什么会产生 yarn,它解决了什么问题, ...
- 第五章第四周习题: Transformers Architecture with TensorFlow
目录 Transformer Network Packages 1 - Positional Encoding 1.1 - Sine and Cosine Angles Exercise 1 - ge ...
- Alpha Scrum Meeting汇总
第一次Alpha Scrum Meeting 第二次Alpha Scrum Meeting 第三次Alpha Scrum Meeting 第四次Alpha Scrum Meeting 第五次Alpha ...
- 【二食堂】Alpha - Scrum Meeting 7
Scrum Meeting 7 例会时间:4.17 11:40 - 12:00 进度情况 组员 昨日进度 今日任务 李健 1. 继续文本区域的开发,先完成目前简陋的添加方式,再区实现勾选功能issue ...
- Mac上安装Grafana
Mac上安装Grafana 一.背景 二.安装步骤 1.通过 Home Brew 安装 2.通过二进制包进行安装 1.下载 2.grafana配置文件的路径 3.修改grafana配置 1.修改默认的 ...
- IE浏览器——网络集合代理无法启动
用管理员身份运行cmd然后输入 sc config diagnosticshub.standardcollector.service start=demand
- Celery Task(定时任务)及参数
celery beat 是一个调度器:它以常规的时间间隔开启任务,任务将会在集群中的可用节点上运行. 默认情况下,入口项是从 beat_schedule 设置中获取,但是自定义的存储也可以使用,例如在 ...
- Vulnhub实战-dr4g0n b4ll靶机👻
Vulnhub实战-dr4g0n b4ll靶机 地址:http://www.vulnhub.com/entry/dr4g0n-b4ll-1,646/ 描述:这篇其实没有什么新奇的技巧,用到的提权方式就 ...
- c++继承关系中成员函数的重载、重写、重定义之间的区别
1.Override.Overload.Redefine Overload 重载只能发生在类内部,不能发生在子类和父类的继承中.具体来说,如果子类中有父类同名.同返回值类型,但是不同参数列表,这两个在 ...