[CF985G]Team Players
题意:给出一个图,求$\sum\limits_{\substack{i\lt j\lt k\\\nexists(i,j),(j,k),(i,k)}}Ai+Bj+Ck$
挺好的一道题==,就是稍微毒了点
考虑容斥,先算$all=\sum\limits_{i\lt j\lt k}Ai+Bj+Ck$
我们枚举$0\leq t\leq n-1$,它作为$i$被计数$\binom{n-1-i}2$次,作为$j$被计数$i(n-1-i)$次,作为$k$被计数$\binom i2$次,直接统计即可
再算$sub_1=\sum\limits_{\substack{i\lt j\lt k\\\exists(i,k)\text{or}(j,k)}}Ai+Bj+Ck$
我们枚举$k$和$x\left(x\lt k,\exists(x,k)\right)$,如果$i=x$,那么$j\in[x+1,k-1]$,如果$j=x$,那么$i\in[0,x-1]$,直接统计就好了
这样重复统计了$\exists(i,k),(j,k)$的情况,我们把$k$的邻居排序后统计一下即可
最后算$sub_2=\sum\limits_{\substack{i\lt j\lt k\\\exists(i,j),\nexists(i,k),(j,k)}}Ai+bj+Ck$
这一部分也用容斥做,拆成$[\exists(i,j)]-[\exists(i,j),(i,k)]-[\exists(i,j),(j,k)]+[\exists(i,j),(i,k),(j,k)]$
第一部分:把所有$(i,j)$排序后从小到大枚举$k$单调地更新答案即可
第二部分:枚举$(i,k)$,在$i$的邻接表中查询$[i+1,k-1]$的节点和,这个维护前缀和就可以了
第三部分:枚举$(j,k)$,在$j$的邻接表中查询$[0,j-1]$的节点和,同样维护前缀和即可
第四部分:相当于是图中的三元环计数,题解给了一个挺不错的idea,或许能用在其他地方
我们把所有点按度数分类,度数$\geq\sqrt m$称为重点,否则称为钦轻点,显然重点只有$O(\sqrt m)$个
对每个重点$i$预处理出邻接矩阵$cn_{i,j}$,这里用bitset存是毫无压力的
我们枚举$k$,如果$k$是重点,那么直接枚举所有$(i,j)$并检查$cn_{k,i}$和$cn_{k,j}$即可,这一步的时间复杂度是$O(m\sqrt m)$的
如果$k$是轻点,那么先枚举$j(j\lt k,\exists(j,k))$
如果$j$是重点,那么直接枚举$i(i\lt j,\exists(i,k))$并用$cn_{j,i}$判断即可,这里的复杂度是$O\left(\sum\limits_{i\,是轻点}deg_i^2\right)=O\left(\sqrt m\sum\limits_{i\,是轻点}deg_i\right)=O(m\sqrt m)$(因为用$\sqrt m$替换$deg_i$,所以这里不是满的)
如果$j$是轻点,我们先给所有$j$的邻居打上标记,然后再枚举$i(i\lt j,\exists(i,k))$并用之前打上的标记判断即可,枚举$i,j$的时间复杂度同上,打标记的时间复杂度可以这样分析:因为$j$会被执行这种操作$O(deg_j)$次,而每次打标记花费$O(deg_j)$的时间,所以时间复杂度仍然同上
最后的答案就是$all-sub_1-sub_2$了
总时间复杂度$O(m\sqrt m)$,后面几个部分都卡到这里了,不得不说还是有点巧妙的...
#include<stdio.h> #include<algorithm> #include<vector> #include<bitset> using namespace std; typedef unsigned long long ll; vector<int>g[200010]; int n,m; ll A,B,C; ll C2(ll n){return n*(n-1)/2;} ll S(ll l,ll r){return l<=r?(l+r)*(r-l+1)/2:0;} ll all(){ int i; ll s=0; for(i=0;i<n;i++)s+=A*i*C2(n-1-i)+B*i*i*(n-1-i)+C*i*C2(i); return s; } int t[200010]; ll sub1(){ int i,j,M; ll s=0,cnt; for(i=0;i<n;i++){ M=0; for(int x:g[i]){ if(x<i){ M++; t[M]=x; s+=(i-x-1)*(A*x+C*i)+B*S(x+1,i-1)+x*(B*x+C*i)+A*S(0,x-1); } } cnt=0; for(j=2;j<=M;j++){ cnt+=t[j-1]; s-=(j-1)*(B*t[j]+C*i)+A*cnt; } } return s; } struct edge{ int x,y; edge(int a=0,int b=0){x=a;y=b;} }e[200010]; bool operator<(edge a,edge b){return a.y<b.y;} vector<ll>sum[200010]; int h[200010]; struct pr{ int l,r; pr(int a=0,int b=0){l=a;r=b;} }p; pr query(int i,int l,int r){ if(g[i].empty()||l>r)return 0; r=upper_bound(g[i].begin(),g[i].end(),r)-g[i].begin()-1; if(r<0)return 0; l=lower_bound(g[i].begin(),g[i].end(),l)-g[i].begin()-1; if(l<0)return pr(r+1,sum[i][r]); return pr(r-l,sum[i][r]-sum[i][l]); } int he[200010]; bool cur[200010]; bitset<200000>cn[1000]; const int bl=450; ll sub2(){ ll ts,s0,s1,s2,s3,sab; int i,j,N; sort(e+1,e+m+1); sab=s0=ts=0; j=1; for(i=0;i<n;i++){ s0+=sab+i*ts*C; while(j<=m&&e[j].y==i){ sab+=e[j].x*A+e[j].y*B; ts++; j++; } } s1=0; for(i=1;i<=m;i++){ p=query(e[i].x,e[i].x+1,e[i].y-1); s1+=p.l*(A*e[i].x+C*e[i].y)+B*p.r; } s2=0; for(i=1;i<=m;i++){ p=query(e[i].x,0,e[i].x-1); s2+=p.l*(B*e[i].x+C*e[i].y)+A*p.r; } N=0; for(i=0;i<n;i++){ if(g[i].size()>=bl){ he[i]=++N; for(int x:g[i])cn[N][x]=1; } } s3=0; for(i=0;i<n;i++){ if(he[i]){ for(j=1;j<=m&&e[j].y<i;j++){ if(cn[he[i]][e[j].x]&&cn[he[i]][e[j].y])s3+=A*e[j].x+B*e[j].y+C*i; } }else{ for(int k:g[i]){ if(k>=i)break; if(he[k]){ for(int j:g[i]){ if(j>=k)break; if(cn[he[k]][j])s3+=A*j+B*k+C*i; } }else{ for(int j:g[k])cur[j]=1; for(int j:g[i]){ if(j>=k)break; if(cur[j])s3+=A*j+B*k+C*i; } for(int j:g[k])cur[j]=0; } } } } return s0-s1-s2+s3; } int main(){ int i,j,x,y; scanf("%d%d%I64u%I64u%I64u",&n,&m,&A,&B,&C); for(i=1;i<=m;i++){ scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); if(x>y)swap(x,y); e[i]=edge(x,y); } for(i=0;i<n;i++){ if(!g[i].empty()){ sort(g[i].begin(),g[i].end()); sum[i].push_back(g[i][0]); for(j=1;j<(int)g[i].size();j++)sum[i].push_back(sum[i][j-1]+g[i][j]); } } printf("%I64u",all()-sub1()-sub2()); }
[CF985G]Team Players的更多相关文章
- BZOJ.5407.girls/CF985G. Team Players(三元环计数+容斥)
题面 传送门(bzoj) 传送门(CF) \(llx\)身边妹子成群,这天他需要从\(n\)个妹子中挑出\(3\)个出去浪,但是妹子之间会有冲突,表现为\(i,j\)之间连有一条边\((i,j)\), ...
- CodeForces985G Team Players
G. Team Players time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- Codeforces 985G. Team Players
Description 有 \(n\) 个人 , \(m\) 对人有冲突 , 你要从这 \(n\) 个人中选出三个人成为一组 , 使得同一组的人不存在一对有冲突 题面 Solution 容斥 答案=总 ...
- Codeforces 985G - Team Players(三元环)
Codeforces 题目传送门 & 洛谷题目传送门 真·ycx 做啥题我就做啥题 考虑枚举 \(j\),我们预处理出 \(c1_i\) 表示与 \(i\) 相连的编号 \(<i\) 的 ...
- Ten Qualities of an Effective Team Player
If you were choosing team members for a business team in your organization, who would the best team ...
- Model--汇总
NSFileManager.NSURL.NSFileHandle.NSData.NSXMLParser.NSUserDefaults.NSKeyedArchiver.NSKeyedUnarchiver ...
- 《C#本质论》读书笔记(14)支持标准查询操作符的集合接口
14.2.集合初始化器 使用集合初始化器,程序员可以采用和数组相似的方式,在集合的实例化期间用一套初始的成员来构造这个集合. 如果没有集合初始化器,就只有在集合实例化后才能显示添加到集合中--例如 ...
- ng-repeat的group
http://blog.csdn.net/violet_day/article/details/17023219 一.obj包含 <!doctype html> <html ng- ...
- ios9基础知识(技能篇)
NSFileManager.NSURL.NSFileHandle.NSData.NSXMLParser.NSUserDefaults.NSKeyedArchiver.NSKeyedUnarchiver ...
随机推荐
- bzoj 1927 网络流
首先我们可以知道这道题中每个点只能经过一次,那么我们引入附加源汇source,sink,那么我们可以将每个点拆成两个点,分别表示对于图中这个节点我们的进和出,那么我们可以连接(source,i,1,0 ...
- vue双向数据绑定的原理-object.defineProperty() 用法
有关双向数据绑定的原理 关于数据双向绑定的理解:利用了 Object.defineProperty() 这个方法重新给对象定义了新属性,在操作新属性分别为为获取属性值(调用get方法)和设置属性值(调 ...
- 【设计模式】享元模式(Flyweight)
摘要: 1.本文将详细介绍享元模式的原理和实际代码中特别是Android系统代码中的应用. 纲要: 1. 引入享元模式 2. 享元模式的概念及优缺点介绍 3. 享元模式在Android源码中的应用 1 ...
- Linux 删除带有特殊字符的文件
Linux 删除带有特殊字符的文件 http://www.cnblogs.com/tester-hehehe/p/5715128.html
- mongodb 学习笔记 2 --- 修改器
修改器是为了爱update文档时,不需要传入整个文档就能修改当前文档的某个属性值,修改器用法如下: 假设数据库中foo集合中存在如下文档:{"name":"jack&qu ...
- C基础入门 - 第一章 - C语言绪言
第1章 C语言绪言 1.1 C语言概述 1.1.1 C语言世界 1.1.2 C语言学习, 能当饭吃吗 1.2 开发环境构建 1.2.1 visual studio安装使用 1.2.2 visual s ...
- 经典卷积网络模型 — LeNet模型笔记
LeNet-5包含于输入层在内的8层深度卷积神经网络.其中卷积层可以使得原信号特征增强,并且降低噪音.而池化层利用图像相关性原理,对图像进行子采样,可以减少参数个数,减少模型的过拟合程度,同时也可以保 ...
- HighGUI图形图像界面初步——鼠标操作
OpenCV中的鼠标操作和滑动条的消息映射方式很类似,都是通过一个中介函数配合一个回调函数来实现的,创建和指定滑动条回调函数为createTrackbar, 而指定鼠标操作消息回调函数的函数为setM ...
- 【LabVIEW技巧】工厂模式_简单工厂
前言 上一个文章介绍了如何学习LabVIEW OOP,简要的提及了一些OOP学习中注意的事项,许多文章的读者反映写的太范,后文会逐步缩小范围,讨论在LabVIEW中各个模式的应用. 工厂模式概述 工厂 ...
- Java-贪心算法
1. 什么是贪心算法? 贪心算法,又称贪婪算法(Greedy Algorithm),是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优解出发来考虑,它所做出的仅是在某种意义上的 ...