Codeforces Round #621 (Div. 1 + Div. 2)E(二分查找,枚举分界点,容斥原理)
可以把每头牛看作一个位置,有几对牛可以放置相当于有几对位置可以给它睡觉,没有牛可以在其他牛的位置睡觉,所以有几对牛放置的可能答案就乘多少(相当于在原本的两个集合里分别插入一个元素,元素代表它睡觉的位置)
容斥的时候,第二遍会把当前位置i+1这个点没有牛在睡觉的情况全部去掉,尝试写了不容斥,直接计算当前枚举位置i一定有牛睡觉的方法,发现巨麻烦无比,遂放弃55555
#define HAVE_STRUCT_TIMESPEC
#include<bits/stdc++.h>
using namespace std;
int a[];
vector<int>v[];
int l[],r[];
const long long mod =1e9+;
int n,m;
int binary_search_(int color,int num){
int point=upper_bound(v[color].begin(),v[color].end(),num)-v[color].begin();
return point;
}
pair<int,long long> solve(){
long long sum=;
int ans=;
for(int i=;i<=n;++i){//枚举草的颜色
int x=binary_search_(i,l[i]);//有x头牛可以放在左边
int y=binary_search_(i,r[i]);//有y有牛可以放在右边
if(x*y-min(x,y)>){//两边都可以有牛放置
ans+=;
sum=(sum*(x*y-min(x,y)))%mod;//每头牛停止的位置是唯一的(数据保证不存在喜爱相同颜色且数量也相同的牛)
//有几对喜爱吃颜色i草的牛,答案就乘多少,可以把每头牛看作一个位置,有几对牛可以放置相当于有几对位置可以给它睡觉,没有牛可以在其他牛的位置睡觉,所以有几对牛放置的可能答案就乘多少(相当于在原本的两个集合里分别插入一个元素,元素代表它睡觉的位置)
}
else if(x||y){//只有一边可以有牛放置或者两边只能放置同一头牛
++ans;
sum=(sum*(x+y))%mod;//两种情况对答案产生的影响都是x+y,前者x或y有一个是0,后者x和y都是1
}
}
return make_pair(ans,sum);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>n>>m;
for(int i=;i<=n;++i){
cin>>a[i];
++r[a[i]];//[i,n]区间里a[i]出现的次数
}
for(int i=;i<=m;++i){
int x,y;
cin>>x>>y;
v[x].emplace_back(y);
}
for(int i=;i<=n;++i)
sort(v[i].begin(),v[i].end());
int ans=;
long long num=;
for(int i=;i<=n;++i){//以i+0.5为分界点
--r[a[i]];//分界点以右a[i]出现次数-1(a[i]被划到了左边)
++l[a[i]];//分界点以左a[i]出现次数+1(a[i]被划到了左边)
pair<int,long long>pr=solve();
if(pr.first>ans){
ans=pr.first;
num=pr.second;
}
else if(pr.first==ans)
num=(num+pr.second)%mod;
}
for(int i=;i<=n;++i){
l[a[i]]=;//初始化
++r[a[i]];//回归枚举分界线以前的状态
}
/*举一个重复计算的例子
8 2
1 1 1 1 2 2 2 2
1 2
2 2
答案应输出2 3
不容斥的话会输出2 11
因为当一次枚举分界点的时候i=2~7,牛的最多头数都是2,可是排列方式总数全都加到了sum中
通过容斥可以在第二次枚举分界点的时候i=2~6把多余的方案数去掉
容斥去掉的是实际上被重复计算的那些,可能有多个区间计算了同样的方案,相同方案只计算一次,不同方案还是都应该计入贡献
容斥去掉第i个位置没有牛的情况,这样可以保证所有计算在内的情况必定有牛要在[0,n]枚举区间i位置时睡觉
*/
for(int i=;i<n;++i){//第一次枚举分界点的时候计算了很多重复情况,需要用容斥将它挤掉
//新的分界左边区间是[0,i],右边区间是[i+2,n]
--r[a[i+]];
++l[a[i]];
pair<int,long long>pr=solve();
if(pr.first==ans)
num=(mod+num-pr.second)%mod;//去掉重复计算的次数
}
cout<<ans<<" "<<num;
return ;
}
Codeforces Round #621 (Div. 1 + Div. 2)E(二分查找,枚举分界点,容斥原理)的更多相关文章
- Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship
Problem Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...
- Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)
Problem Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...
- Educational Codeforces Round 43 (Rated for Div. 2)
Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...
- Educational Codeforces Round 35 (Rated for Div. 2)
Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...
- Educational Codeforces Round 63 (Rated for Div. 2) 题解
Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...
- Educational Codeforces Round 39 (Rated for Div. 2) G
Educational Codeforces Round 39 (Rated for Div. 2) G 题意: 给一个序列\(a_i(1 <= a_i <= 10^{9}),2 < ...
- Educational Codeforces Round 48 (Rated for Div. 2) CD题解
Educational Codeforces Round 48 (Rated for Div. 2) C. Vasya And The Mushrooms 题目链接:https://codeforce ...
- Educational Codeforces Round 60 (Rated for Div. 2) 题解
Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...
随机推荐
- IIS在已有站点上->添加应用程序命令
已有站点:HTTP80 %systemroot%\system32\inetsrv\APPCMD ADD APP /SITE.NAME:"HTTP80" /path:/Redire ...
- css字体样式+文本样式
font-family属性值:具体字体名或者字体集 如果是中文或者有单词之间有空格,需要加双引号 字体集: Serif (有装饰线) Sans-serif (无装饰线) Monospace Cursi ...
- oracle 取某个时间的数据(每周几的上午几点到几点)
select count(*),t.分组字段 from (select t.* ,to_char(t.时间,'HH24') stime,to_char(t.时间,'HH24mi') fz,to_cha ...
- linux 下查看json 文件 使用jq工具
安装 文档 yum 安装 yum search jq yum -y install jq.x86_64 apt-get install jq jq支持查看 jq . json 文件 查看json文件 ...
- Centos 7 安装配置git
Centos 7 安装配置git 1.安装git yum install git 2.验证git git -version 3.配置基本信息
- warning Attribute 'showExpand' must be hyphenated
报错翻译:警告属性“ showExpand”必须带连字符 报错原因父组件给子组件传参时,使用驼峰命名法,导致ESLint检测出语法问题,如下↓ 改成这样就ok了
- lvs使用进阶
之前lvs基础篇(https://www.cnblogs.com/ckh2014/p/10855002.html)中介绍了lvs-dr的搭建,下面我们再复习一下,架构如下: 相关配置 director ...
- claim、claimsidentity、claimsprincipal
Claim表示一个声明单元,它用来组成ClaimsIdentity.ClaimsIdentity表示一个证件,例如身份证,身份证上面的名字表示一个Claim,身份证号也表示一个Claim,所有这些Cl ...
- KiKi's K-Number HDU - 2852 树状数组+二分
#include<iostream> #include<cstring> using namespace std; ; int tr[N]; int lowbit(int x) ...
- AI数学基础:符号
1.sigma 表达式 ∑ 是一个求和符号,英语名称:Sigma,汉语名称:西格玛(大写Σ,小写σ) 第十八个希腊字母.在希腊语中,如果一个单字的最末一个字母是小写sigma,要把该字母写成 ς ,此 ...