题意

有一个定义在 k 维非负整点上的函数:$f(x_1,x_2,...,x_k):N_{0}^{k}->\{0,1\}$ ,定义方法如下:

若存在$j∈[1,k],x_j=0$,则$f(x_1,x_2,...,x_k)=0$

若对$j∈[1,k]$都有$x_j=1$则$f(x_1,x_2,...,x_k)=1$

否则$f(x_1,x_2,...,x_k)=(\sum_{j=1}^{k}{f(x_1,...,x_{j-1},x_j-1,x_{j+1},...,x_k)})mod 2$

现在给出k,并对每一维坐标给出区间$l_i,r_i$,求:

$\sum_{x_1∈[l_1,r_1],...,x_k∈[l_k,r_k]}{f(x_1,x_2,...,x_k)}$

$1\leq T \leq 10,1 \leq k \leq 9,1 \leq l_j,r_j \leq 10^{15}$。


思考

对于k,某个点的f值为1的充要条件是所有维度在二进制表示下没有交集,即$x_i\&x_j=0,i≠j$。

由于每个维度都有一个限制,不好算,因此我们容斥每个维度是否满足限制。这样,问题转化为选k个数,第i个数最多能选$a_i$个,每一个二进制位上最多有一个1的方案数。设f[i][0/1][S]表示从高位到低位填到第i个数,0/1是当前有没有选1,S是k个数是否达到上限的方案数。每次转移时,考虑当前这一位填不填1即可。

复杂度$O(T*2^{(2k)}*n)$,需要卡常。


代码

  1. // luogu-judger-enable-o2
  2. #define mod 990804011
  3. #include<bits/stdc++.h>
  4. using namespace std;
  5. typedef long long int ll;
  6. int T;
  7. int k;
  8. ll ans,L[],R[];
  9. ll f[][][<<];
  10. bool vis[<<][<<];
  11. int BASE,dig[];
  12. int d[];
  13. struct node
  14. {
  15. int S1,S2;
  16. ll val;
  17. node(int a=,int b=,ll c=):S1(a),S2(b),val(c){}
  18. };
  19. inline ll get(ll S,ll x)
  20. {
  21. return (S&((ll)(ll)<<x))>;
  22. }
  23. inline ll newlimit(ll D,ll nowD,ll limit)
  24. {
  25. return ((D^nowD)^(BASE))&limit;
  26. }
  27. inline ll max(ll x,ll y)
  28. {
  29. return x>y?x:y;
  30. }
  31. inline ll calc(int S)
  32. {
  33. ll maxx=;
  34. for(int i=;i<=;++i)
  35. dig[i]=;
  36. for(int i=;i<k;++i)
  37. {
  38. if(S&((ll)<<i))
  39. {
  40. if(L[i]==)
  41. return ;
  42. for(int j=;j<=;++j)
  43. dig[j]|=get(L[i]-,j)<<i;
  44. maxx=max(maxx,L[i]);
  45. }
  46. else
  47. {
  48. for(int j=;j<=;++j)
  49. dig[j]|=get(R[i],j)<<i;
  50. maxx=max(maxx,R[i]);
  51. }
  52. }
  53. int base=log2(maxx)+;
  54. memset(f,,sizeof(f));
  55. f[base][][(<<k)-]=;
  56. for(register int i=base;i>=;--i)
  57. {
  58. for(register int S=;S<(<<k);++S)
  59. if(f[i][][S])
  60. {
  61. register int x=newlimit(dig[i-],,S);
  62. f[i-][][x]=(f[i-][][x]+f[i][][S])%mod;
  63. }
  64. for(register int S=;S<(<<k);++S)
  65. if(f[i][][S])
  66. {
  67. register int x=newlimit(dig[i-],,S);
  68. f[i-][][x]=(f[i-][][x]+f[i][][S])%mod;
  69. }
  70. for(register int S=;S<(<<k);++S)
  71. if(f[i][][S])
  72. for(register int d1=;d1<k;++d1)
  73. if(get(S,d1)==||get(dig[i-],d1)==)
  74. {
  75. register int x=newlimit(dig[i-],<<d1,S);
  76. f[i-][][x]=(f[i-][][x]+f[i][][S])%mod;
  77. }
  78. for(register int S=;S<(<<k);++S)
  79. if(f[i][][S])
  80. for(register int d=;d<k;++d)
  81. if(get(S,d)==||get(dig[i-],d)==)
  82. {
  83. register int x=newlimit(dig[i-],<<d,S);
  84. f[i-][][x]=(f[i-][][x]+f[i][][S])%mod;
  85. }
  86. }
  87. ll sum=;
  88. for(register int S=;S<(<<k);++S)
  89. sum=(sum+f[][][S]+f[][][S])%mod;
  90. return sum;
  91. }
  92. void dfs(int s,int S,int G)
  93. {
  94. if(s==k)
  95. {
  96. ll x=calc(S);
  97. if(G&)
  98. ans=(ans-x+mod)%mod;
  99. else
  100. ans=(ans+x)%mod;
  101. return;
  102. }
  103. dfs(s+,S,G);
  104. dfs(s+,S|((ll)<<s),G+);
  105. }
  106. inline void solve()
  107. {
  108. cin>>k;
  109. for(int i=;i<k;++i)
  110. {
  111. cin>>L[i]>>R[i];
  112. --L[i],--R[i];
  113. }
  114. ans=;
  115. BASE=((ll)<<k)-;
  116. dfs(,,);
  117. cout<<ans<<endl;
  118. }
  119. int main()
  120. {
  121. ios::sync_with_stdio(false);
  122. cin>>T;
  123. while(T--)
  124. solve();
  125. return ;
  126. }

[校内训练19_09_03]c Huge Counting的更多相关文章

  1. [4.14校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi....        很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...

  2. [2017.4.7校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 报警啦.......hzwer又出丧题虐人啦..... 4道ctsc...有一道前几天做过了,一道傻逼哈希还wa了十几次,勉强过了3题..我好 ...

  3. [3.24校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...

  4. 19_04_19校内训练[Game]

    题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...

  5. 19_04_02校内训练[deadline]

    题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...

  6. 平面图转对偶图&19_03_21校内训练 [Everfeel]

    对于每个平面图,都有唯一一个对偶图与之对应.若G‘是平面图G的对偶图,则满足: G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面. 直观地讲,红色标出来的图就是蓝色标出的图的对偶图 ...

  7. fzyzojP3979 -- [校内训练20180914]魔法方阵

    原题见CF632F https://blog.csdn.net/Steaunk/article/details/80217764 这个比较神仙了 点边转化, 把max硬生生转化成了路径最大值,再考虑所 ...

  8. fzyzojP3580 -- [校内训练-互测20180315]小基的高智商测试

    题目还有一个条件是,x>y的y只会出现一次(每个数直接大于它的只有一个) n<=5000 是[HNOI2015]实验比较 的加强版 g(i,j,k)其实可以递推:g(i,j,k)=g(i- ...

  9. fzyzojP3372 -- [校内训练20171124]博弈问题

    对于每个点都要答案 还是异或 trie树合并石锤了 朴素枚举是O(n^2*17)的 怎么办呢? 我们发现合并的时候,一些部分的trie的子树还是不变的 改变的部分也就是合并的复杂度可以接受 鉴于大部分 ...

随机推荐

  1. Arcgis api for javascript学习笔记(3.2版本) - 匀速行驶轨迹动画效果

    一.前言 有这样一个需求:已知某条线上的n个点的经纬度数组 ,实现物体运行轨迹. 如果这些点中两个距离很近,那么我们可以用一个定时器在地图上每次重新画一个点,这样肉眼看到这个点上的运动效果,如下图代码 ...

  2. Libra和中国央行数字货币(DCEP)的对比

    最近偶然和朋友讨论起Libra,对Libra和央行的数字货币方案很感兴趣.梳理了阅读资料(参考见文末)和自己的思考,发知乎留个记录. Libra 是什么? 无国界货币 + 为全球数十亿人服务的金融基础 ...

  3. [Python之路] 内存管理&垃圾回收

    一.python源码 1.准备源码 下载Python源码:https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz 解压得到文件夹: 我们主要关 ...

  4. 33.python之操作系统,进程,线程

    转载:https://www.cnblogs.com/yuanchenqi/articles/6248025.html 操作系统 一 为什么要有操作系统? 现代计算机系统是由一个或者多个处理器,主存, ...

  5. Excel数据处理

    合并计算: 数据面板下的合并计算 然后设置好合并计算的区域 以及勾选 首行跟最左列

  6. mac如何查看已连接wifi的密码

    可以通道mac自带的“钥匙串访问”功能查看.选择需要查询的wifi名称,右击选择“将密码拷贝到剪贴板”,输入管理员密码后,密码就拷贝好了. 找个地方粘贴即可看到密码

  7. 转载:通过监控Nginx日志来实时屏蔽高频恶意访问的IP

    通过监控Nginx日志来实时屏蔽高频恶意访问的IP   目前在我的VPS上主要通过两种方式来限制ip的访问次数. 通过Nginx的limit_req配置来限制同一ip在一分钟内的访问次数 通过Ngin ...

  8. 只用这 6 个字符,就可以写出任意 JavaScript 代码!

    你可能在网上见过有人用 几个不同的字符写的各种稀奇古怪的 JavaScript 代码,虽然看起来奇怪,但是能正常运行!比如这个: (!(~+[])+{})[--[~+""][+[] ...

  9. zabbix监控web应用日志报警并发送消息到钉钉

    首先在钉钉上开启钉钉机器人功能 说明:自定义关键词是zabbix发送过来的消息内容必须含有你定义的ERROR或者error字段,否则消息无法发送过来 ip地址段:一般都是zabbix-server的I ...

  10. 《C++Primer》第五版习题答案--第二章【学习笔记】

    C++Primer第五版习题解答---第二章 ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/9 第二章:变量和基本类型 练习2.1: 类 ...