[IOI2008] Fish 鱼
https://www.luogu.org/recordnew/lists?uid=56840
题解
首先可以发现我们对于每种颜色的鱼,长一点的能够覆盖的方案已定完全包含短一点的方案。
所以我们可以只对每种颜色最长的鱼计算贡献。
然后有一个\(naive\)的想法,我们从按照最长的鱼的长度小到大枚举每种颜色,然后算出那条最长的鱼能够包含的方案。
这样会算重。
那么我们还有一个\(naive\)的想法,我们可以在枚举的时候,只维护出比在a这种颜色前面的颜色的所有方案。
这样会算少。
考虑在什么情况吗,没有被算到。
对于两种颜色\(a,b\),我们本该在枚举a的时候枚举(a,b)这种集合,结果由于排序所以没有枚举到,但在枚举b的时候因为长度原因没有够到a。
所以我们在枚举a的时候,当我们没有拿走能够拿走的所有a的时候可以按照上面的方法做,但是如果a的全部拿走了,我们需要把所有颜色b算出来,这些b可以拿到的颜色个数是和a一样的。
这样的话,a的数量是now+1的,枚举到b是最多枚举到now,所以不会算重。
我也不知道我在写啥
代码
#include<bits/stdc++.h>
#define N 500009
using namespace std;
typedef long long ll;
int n,k,mod,cnt[N];
int id[N],pos[N],ct[N];
int now[N],nxt[N];
int mx[N],_mx[N];
ll ans;
inline ll rd(){
ll x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
inline void MOD(ll &x){x=x>=mod?x-mod:x;}
inline bool cmp(int a,int b){return mx[a]<mx[b];}
struct node{
int len,co;
inline bool operator <(const node &b)const{
return len<b.len;
}
}a[N];
struct segment{
int tr[N<<2];
void upd(int cnt,int l,int r,int x){
if(l==r){tr[cnt]++;return;}
int mid=(l+r)>>1;
if(mid>=x)upd(cnt<<1,l,mid,x);
else upd(cnt<<1|1,mid+1,r,x);
tr[cnt]=1ll*tr[cnt<<1]*tr[cnt<<1|1]%mod;
}
void build(int cnt,int l,int r){
tr[cnt]=1;
if(l==r)return;
int mid=(l+r)>>1;
build(cnt<<1,l,mid);build(cnt<<1|1,mid+1,r);
}
ll query(int cnt,int l,int r,int L,int R){
if(L>R)return 1;
if(l>=L&&r<=R)return tr[cnt];
int mid=(l+r)>>1;
if(mid>=L&&mid<R)return query(cnt<<1,l,mid,L,R)*query(cnt<<1|1,mid+1,r,L,R)%mod;
if(mid>=L)return query(cnt<<1,l,mid,L,R);
if(mid<R)return query(cnt<<1|1,mid+1,r,L,R);
}
inline void init(int n){build(1,1,n);}
}T;
inline int efs(int num,int l,int r){
int ans=l;
while(l<=r){
int mid=(l+r)>>1;
if(_mx[mid]<num)ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
int main(){
n=rd();
k=rd();
mod=rd();
for(int i=1;i<=n;++i){
a[i].len=rd();a[i].co=rd();
mx[a[i].co]=max(mx[a[i].co],a[i].len);
}
sort(a+1,a+n+1);
for(int i=1;i<=k;++i)id[i]=i;
sort(id+1,id+k+1,cmp);
for(int i=1;i<=k;++i)pos[id[i]]=i,_mx[i]=mx[id[i]];
for(int i=n;i>=1;--i){
a[i].co=pos[a[i].co];
cnt[a[i].co]++;
nxt[i]=now[a[i].co];
now[a[i].co]=i;
}
T.init(k);
int p=1;
for(int i=1;i<=n;++i){
cnt[a[i].co]--;
while(a[p].len*2<=a[i].len)now[a[p].co]=nxt[now[a[p].co]],T.upd(1,1,k,a[p].co),ct[a[p].co]++,p++;
if(!cnt[a[i].co]){
int ps=efs(a[now[a[i].co]].len*2,a[i].co,k);
ll x=T.query(1,1,k,1,a[i].co-1);
MOD(ans+=x*ct[a[i].co]%mod);
MOD(ans+=x*T.query(1,1,k,a[i].co+1,ps)%mod);
}
}
cout<<ans;
return 0;
}
[IOI2008] Fish 鱼的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- C++多态的实现及原理详细解析
C++多态的实现及原理详细解析 作者: 字体:[增加 减小] 类型:转载 C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型 ...
- C++多态的实现原理
1. 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 2. 存在虚函数的类都有一个一维的虚函数表叫做虚表.类的对象有一个指向虚表开始的虚指针.虚表是和类对应的,虚表指针是和对象 ...
- C++ 多态的实现及原理
C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数.如果对象类型是派生类,就调用派生类的函数:如果对象类型是基类 ...
- 学JAVA第十五天,方法重载及构造方法进一步了解
由于星期五生病了,所以就没写.今天上课,又来写了!!! 先来说方法的重载. 方法的重载就是有两个方法的方法名相同,但参数不一致,参数个数不一致,或参数的类型不一样. package pkg9;publ ...
- 设计模式系列之装饰模式(Decorator Pattern)
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了一个装饰类,用来包装原 ...
- 多态练习题(通过UML建模语言来实现饲养员喂养动物)
项目需求如下图: package com.Summer_0428.cn; /** * @author Summer * 1.构建一个食物抽象类,Bone和Fish分别为其实现类,通过super传参. ...
- 英语口语练习系列-C41-食物词汇-鹊桥仙
词汇 1, rice [raɪs] n. 稻:米饭 vt. 把-捣成米糊状 Rice: 米饭 | 大米 | 稻 2, bread [bred] n. 面包:生计 vt. 在-上洒面包屑 Bread: ...
- 多邻国学英语 tips
来源: https://www.cnblogs.com/daysme整理了一分多邻国学英语中的相关语法文档. 地方 null 现在完成时 null 反身代词 浓缩的精华:反身代词就是 “XX 自己” ...
随机推荐
- 惠普IPMI登陆不上
[问题描述] IPMI登陆不上(HP),点击无反应. 浏览器使用IE,java版本使用32位1.7版本. [问题原因] 保护此网站的证书使用弱加密,即 SHA1.此网站应该在 SHA1 被禁用之前将该 ...
- git的配置设置
git的基本配置 git是一个版本控制工具,既然是工具,那么就可以根据人的个人喜好来进行设置,git也提供了配置,可以根据自己的喜好来对它进行个性化的设计,以让自己舒服的玩. git有三个配置文件 / ...
- 使用css3的repeating-linear-gradient画虚线
还在用 border-style: dashed 画虚线吗?虽然也是虚线,但是不能控制每一个虚线的宽度 .dashed { height: 1px; background-image: repeati ...
- js中的数组去掉空值
//result 是有空值的数组//r是处理好的数组var r = result.filter(function (s) { return s && s.trim();});
- react 从商品详情页返回到商品列表页,列表自动滚动上次浏览的位置
现状:目前从商品详情页返回到商品列表页,还需要再去请求服务数据,还需要用户再去等待获取数据的过程,这样用户体验非常不好, 遇到的问题: 1:如何将数据缓存, 2:如何获取和保存列表滑动的高度, 3:判 ...
- MySQL索引优化(索引单表优化案例)
1.单表查询优化 建表SQL CREATE TABLE IF NOT EXISTS `article` ( `id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUT ...
- Linux用户的基本操作1 用户相关信息 及useradd /usermod 部分
目录 linux 用户管理 - 用户的基本操作 用户管理 用户的相关命令 linux 用户管理 - 用户的基本操作 用户管理 1.什么是用户? 用户指的是能够正常登录Linux或windows系统 2 ...
- Spring缓存机制(转)
Spring的缓存机制非常灵活,可以对容器中任意Bean或者Bean的方法进行缓存,因此这种缓存机制可以在JavaEE应用的任何层次上进行缓存. Spring缓存底层也是需要借助其他缓存工具来实现,例 ...
- ASP.NET Core 基础知识(五) 依赖关系注入
参考https://www.cnblogs.com/jesse2013/p/di-in-aspnetcore.html 和 https://www.cnblogs.com/artech/p/net-c ...
- 浅析拯救小矮人的 nlogn 算法及其证明
浅析拯救小矮人的 nlogn 算法及其证明 题型简介: 有 $ n $ 个人,第 $ i $ 个人身高 $ a_i $ 手长 $ b_i $ ,他们为了从一个高为 $ H $ 的洞中出去,决定搭人梯. ...