可以把每头牛看作一个位置,有几对牛可以放置相当于有几对位置可以给它睡觉,没有牛可以在其他牛的位置睡觉,所以有几对牛放置的可能答案就乘多少(相当于在原本的两个集合里分别插入一个元素,元素代表它睡觉的位置)

容斥的时候,第二遍会把当前位置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(二分查找,枚举分界点,容斥原理)的更多相关文章

  1. 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 ...

  2. 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 ...

  3. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  4. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

  5. 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 ...

  6. 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 ...

  7. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  8. 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 < ...

  9. Educational Codeforces Round 48 (Rated for Div. 2) CD题解

    Educational Codeforces Round 48 (Rated for Div. 2) C. Vasya And The Mushrooms 题目链接:https://codeforce ...

  10. Educational Codeforces Round 60 (Rated for Div. 2) 题解

    Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...

随机推荐

  1. 将一个Head下的Line复制到另一个Head下(ef+linq)

    今天工作中有一个需求,要求将一个Item下的Line复制到另外一个Item下面 这个需求在工作中很多,按照以往的经验肯定是先delete from,然后再一条条遍历后insert into 这两天正好 ...

  2. [Python]scatter_matrix报错 module 'pandas' has no attribute 'scatter_matrix'

    运行pandas.scatter_matrix()散点图函数时报错, 原因是该函数在新版本用法发生了变化: pandas.plotting.scatter_matrix 完整用法:pd.plottin ...

  3. 【剑指Offer】61、把二叉树打印成多行

    题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 题解一:BFS public static ArrayList<ArrayList<Integer>> ...

  4. 止损+TS

    单策略单品种单策略多品种多策略单品种和加仓多策略多品种静态仓位和动态仓位 金肯特钠(kingKeltner)布林强盗(BollingerBandit)动态突破(DynamicBreakOutII)恒温 ...

  5. 数据类型(8种)和运算符——Java

    一.什么是标识符,它有什么作用(重点掌握) 1. 标识符指的是 标识符是用户编程时使用的名字,用于给变量.常量.函数.语句块等命名,以建立起名称与使用之间的关系.标识符可由任何字母数字字符串形成. 2 ...

  6. 有关es6的模块化

    假如有两个文件:app.js和config.js app.js为主文件要去引用config这个模块 以前学习node时使用的模块导出: 需求:导出三个成员,分别是 foo: bar f: functi ...

  7. CentOS 编译安装 PyCrypto

    转载自:http://bugcharmer.blogspot.com/2012/07/building-pycrypto-on-amazon-ec2.html Step 1 - Install gcc ...

  8. Java安全笔记

    前言 后端接口开发中,涉及到用户私密信息(用户名.密码)等,我们不能传输明文,必须使用加密方式传输.这次政府项目中,安全测试组提出了明文传输漏洞,抽空研究了下Java加解密相关知识,记录下. 散列函数 ...

  9. linux基础之IO模型

    一.IO模型 一次read操作: (1)等待数据准备好:从磁盘到内核内存 (2)从内核内存复制到进程内存 示意图如下: I/O类型: 同步和异步:synchronous,asynchronous 关注 ...

  10. Java文件与类动手动脑

    动手动脑1: 使用Files. walkFileTree()找出指定文件夹下所有大于指定大小(比如1M)的文件. package classJava; import java.io.IOExcepti ...