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,所以不会算重。

我也不知道我在写啥

代码

  1. #include<bits/stdc++.h>
  2. #define N 500009
  3. using namespace std;
  4. typedef long long ll;
  5. int n,k,mod,cnt[N];
  6. int id[N],pos[N],ct[N];
  7. int now[N],nxt[N];
  8. int mx[N],_mx[N];
  9. ll ans;
  10. inline ll rd(){
  11. ll x=0;char c=getchar();bool f=0;
  12. while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
  13. while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
  14. return f?-x:x;
  15. }
  16. inline void MOD(ll &x){x=x>=mod?x-mod:x;}
  17. inline bool cmp(int a,int b){return mx[a]<mx[b];}
  18. struct node{
  19. int len,co;
  20. inline bool operator <(const node &b)const{
  21. return len<b.len;
  22. }
  23. }a[N];
  24. struct segment{
  25. int tr[N<<2];
  26. void upd(int cnt,int l,int r,int x){
  27. if(l==r){tr[cnt]++;return;}
  28. int mid=(l+r)>>1;
  29. if(mid>=x)upd(cnt<<1,l,mid,x);
  30. else upd(cnt<<1|1,mid+1,r,x);
  31. tr[cnt]=1ll*tr[cnt<<1]*tr[cnt<<1|1]%mod;
  32. }
  33. void build(int cnt,int l,int r){
  34. tr[cnt]=1;
  35. if(l==r)return;
  36. int mid=(l+r)>>1;
  37. build(cnt<<1,l,mid);build(cnt<<1|1,mid+1,r);
  38. }
  39. ll query(int cnt,int l,int r,int L,int R){
  40. if(L>R)return 1;
  41. if(l>=L&&r<=R)return tr[cnt];
  42. int mid=(l+r)>>1;
  43. if(mid>=L&&mid<R)return query(cnt<<1,l,mid,L,R)*query(cnt<<1|1,mid+1,r,L,R)%mod;
  44. if(mid>=L)return query(cnt<<1,l,mid,L,R);
  45. if(mid<R)return query(cnt<<1|1,mid+1,r,L,R);
  46. }
  47. inline void init(int n){build(1,1,n);}
  48. }T;
  49. inline int efs(int num,int l,int r){
  50. int ans=l;
  51. while(l<=r){
  52. int mid=(l+r)>>1;
  53. if(_mx[mid]<num)ans=mid,l=mid+1;
  54. else r=mid-1;
  55. }
  56. return ans;
  57. }
  58. int main(){
  59. n=rd();
  60. k=rd();
  61. mod=rd();
  62. for(int i=1;i<=n;++i){
  63. a[i].len=rd();a[i].co=rd();
  64. mx[a[i].co]=max(mx[a[i].co],a[i].len);
  65. }
  66. sort(a+1,a+n+1);
  67. for(int i=1;i<=k;++i)id[i]=i;
  68. sort(id+1,id+k+1,cmp);
  69. for(int i=1;i<=k;++i)pos[id[i]]=i,_mx[i]=mx[id[i]];
  70. for(int i=n;i>=1;--i){
  71. a[i].co=pos[a[i].co];
  72. cnt[a[i].co]++;
  73. nxt[i]=now[a[i].co];
  74. now[a[i].co]=i;
  75. }
  76. T.init(k);
  77. int p=1;
  78. for(int i=1;i<=n;++i){
  79. cnt[a[i].co]--;
  80. 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++;
  81. if(!cnt[a[i].co]){
  82. int ps=efs(a[now[a[i].co]].len*2,a[i].co,k);
  83. ll x=T.query(1,1,k,1,a[i].co-1);
  84. MOD(ans+=x*ct[a[i].co]%mod);
  85. MOD(ans+=x*T.query(1,1,k,a[i].co+1,ps)%mod);
  86. }
  87. }
  88. cout<<ans;
  89. return 0;
  90. }

[IOI2008] Fish 鱼的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. C++多态的实现及原理详细解析

    C++多态的实现及原理详细解析 作者: 字体:[增加 减小] 类型:转载   C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型 ...

  3. C++多态的实现原理

    1. 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 2. 存在虚函数的类都有一个一维的虚函数表叫做虚表.类的对象有一个指向虚表开始的虚指针.虚表是和类对应的,虚表指针是和对象 ...

  4. C++ 多态的实现及原理

    C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数.如果对象类型是派生类,就调用派生类的函数:如果对象类型是基类 ...

  5. 学JAVA第十五天,方法重载及构造方法进一步了解

    由于星期五生病了,所以就没写.今天上课,又来写了!!! 先来说方法的重载. 方法的重载就是有两个方法的方法名相同,但参数不一致,参数个数不一致,或参数的类型不一样. package pkg9;publ ...

  6. 设计模式系列之装饰模式(Decorator Pattern)

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了一个装饰类,用来包装原 ...

  7. 多态练习题(通过UML建模语言来实现饲养员喂养动物)

    项目需求如下图: package com.Summer_0428.cn; /** * @author Summer * 1.构建一个食物抽象类,Bone和Fish分别为其实现类,通过super传参. ...

  8. 英语口语练习系列-C41-食物词汇-鹊桥仙

    词汇 1, rice [raɪs] n. 稻:米饭 vt. 把-捣成米糊状 Rice: 米饭 | 大米 | 稻 2, bread [bred] n. 面包:生计 vt. 在-上洒面包屑 Bread: ...

  9. 多邻国学英语 tips

    来源: https://www.cnblogs.com/daysme整理了一分多邻国学英语中的相关语法文档. 地方 null 现在完成时 null 反身代词 浓缩的精华:反身代词就是 “XX 自己” ...

随机推荐

  1. Redis的 SLAVEOF 命令

    SLAVEOF host port SLAVEOF 命令用于在 Redis 运行时动态地修改复制(replication)功能的行为. 通过执行 SLAVEOF host port 命令,可以将当前服 ...

  2. Binary Tree Level Order Traversal(二叉树广度优先遍历或逐层遍历)

    来源:https://leetcode.com/problems/binary-tree-level-order-traversal Given a binary tree, return the l ...

  3. 移动端HTML5开发问题汇总-样式篇

    问题:Android 上圆形图片使用 border 时,边框显示变形 解决:给 img 外嵌套一个元素,为其使用圆角 <div> <img src=""> ...

  4. 悼念512汶川大地震遇难同胞——选拔志愿者 HDU 2188 博弈论 巴什博奕

    悼念512汶川大地震遇难同胞--选拔志愿者 HDU 2188 博弈论 巴什博奕 题意 对于四川同胞遭受的灾难,全国人民纷纷伸出援助之手,几乎每个省市都派出了大量的救援人员,这其中包括抢险救灾的武警部队 ...

  5. [多校联考2019(Round 5 T1)] [ATCoder3912]Xor Tree(状压dp)

    [多校联考2019(Round 5)] [ATCoder3912]Xor Tree(状压dp) 题面 给出一棵n个点的树,每条边有边权v,每次操作选中两个点,将这两个点之间的路径上的边权全部异或某个值 ...

  6. win10上安装redis

    1.下载安装包: 下载地址: 链接:https://pan.baidu.com/s/1oGPrfQJvFz-fX_KNcTTNUw 提取码:eake 2.在适合的位置创建一个文件夹,并将下载到的压缩包 ...

  7. [LeetCode] 52. N皇后 II

    题目链接 : https://leetcode-cn.com/problems/n-queens-ii/ 题目描述: n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间 ...

  8. linux中的文件类型以及查看文件类型的方法

    Linux文件类型和文件的文件名所代表的意义是两个不同的概念,在linux中文件类型与文件扩展名没有关系.它不像Windows那样是依靠文件后缀名来区分文件类型的,在linux中文件名只是为了方便操作 ...

  9. c++ Socket客户端和服务端示例版本三(多线程版本)

    客户端 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/soc ...

  10. c/c++基础篇之数据类型转换

    C/C++常见的数据类型转换 1.      常见的单类基本类型转换 (1)强制类型转换 如: int a=(int)(9.87)  结果a=9 char c=(char)(97)  结果为c=’a’ ...