这题一场模拟赛我们出了弱化版(n<=1e6),抄题面给的程序能拿到71分的好成绩
其实后面的29分是加了几个1e9的数据卡人
这糟老头子真是坏得很
正解我们机房看了三天

在这里感谢这篇题解的作者,代码解释得很清晰~

经过打表观察,可以发现:当\(1\le x \le k\)时

如果 \(k\) 为奇数,\(x*2^{y}\) \(mod\) \(k\)的值成环

如果 \(k\) 为偶数,质因数分解\(x\),如果所含因子\(2\)的次数大于\(k\)所含因子\(2\)的次数,那\(x*2^{y}\) \(mod\) \(k\)的值也成环

然而考试时永远发现不了

于是可以对每条链开一棵动态开点线段树,再开一棵线段树处理不在单点上的点,一起用来模拟题目所给的树状数组(\(N\le10^{9}\),直接开树状树组会炸)。

于是可以这么做修改操作:

对于不在链上的点,最多只会跳\(log_{2}^{k}*log_{k}^{n}=log_{2}^{n}\)次就会跳到\(n\)之外或跳到链上,暴力更新就完事了。

对于在链上的点,我们可以找到这条链的链头(找链头的方法详见代码),求出这个点到链头的距离\(dis\),区间更新\(dis\)和链尾之间的点。

查询也差不多的。

更详细的解释见代码:

  1. #include <bits/stdc++.h>
  2. #define N 200010
  3. using namespace std;
  4. int k;
  5. inline void rd(int &x){
  6. int y=0,f=1;char c=getchar();
  7. while(c<'0' || c>'9' ){if(c=='-')f=-1;c=getchar();}
  8. while(c>='0' && c<='9')y=y*10+(c^48),c=getchar();
  9. x=y*f;
  10. }
  11. int num[N],jw[N],go[N][20],to[N][20],pr[N],a[N],fr,dis,u;
  12. bool vis[N];
  13. inline int lowbit(int x){
  14. while(x%k==0) x/=k;
  15. return x%k;
  16. }
  17. inline int lowbitv(int x){
  18. register int lg=0;
  19. while (x%k==0) x/=k,lg++;
  20. x%=k;
  21. while (lg) x*=k,lg--;
  22. return x;
  23. }
  24. void init()//预处理
  25. {
  26. //jw[i]:i所在链上的进位次数
  27. register int cnt,i,j,w,l;
  28. for(i=1;i<=k;++i) for(j=i;j%2==0;j/=2,++pr[i]);
  29. for(i=1;i<k;++i){
  30. cnt=w=0;
  31. if(vis[i] || pr[i]<pr[k]) continue;
  32. int x=i*2%k;a[++cnt]=i,vis[i]=1;
  33. while(x!=i) a[++cnt]=x,vis[x]=1,x=x*2%k;
  34. for(j=1;j<=cnt;++j) w+=(a[j]*2>=k);
  35. for(j=1;j<=cnt;++j){
  36. jw[a[j]]=w,num[a[j]]=cnt;
  37. (j==1)?x=cnt:x=j-1;
  38. to[a[j]][0]=a[x];
  39. go[a[j]][0]=(a[x]*2>=k);
  40. }
  41. //to[i][j]:i向前跳j步跳到的点
  42. //go[i][j]:i向前跳j步的进位次数
  43. for(j=1;j<=18;++j)
  44. for(l=1;l<=cnt;++l){
  45. to[a[l]][j]=to[to[a[l]][j-1] ][j-1];
  46. go[a[l]][j]=go[a[l]][j-1]+go[to[a[l]][j-1] ][j-1];
  47. }
  48. }
  49. }
  50. void GetF(int x)//求链头
  51. {
  52. int lg=0;
  53. while(x%k==0) x/=k,lg++;
  54. fr=lowbit(x),dis=1;int u=(x-fr)/k,i;//u:x的进位次数
  55. //dis=跳的环数*环的长度+剩余长度(没跳完整个环)
  56. dis+=u/jw[fr]*num[fr];
  57. u%=jw[fr];
  58. for(i=18;i>=0;--i){
  59. if(go[fr][i]<=u){
  60. u-=go[fr][i];
  61. dis+=(1<<i);
  62. fr=to[fr][i];
  63. }
  64. }
  65. while(lg) fr*=k,lg--;//由lowbit(x)的链头还原回去x的链头
  66. }
  67. #define mid ((l+r)>>1)
  68. int root1,root2,root3;
  69. struct tr{ int ls,rs,x; };
  70. struct qwq{
  71. tr t[N*60];
  72. int sz=0;
  73. void update(int &o,int l,int r,int L,int R,int v){
  74. if(!o) o=++sz;
  75. if(L<=l && r<=R){
  76. t[o].x^=v;
  77. return;
  78. }
  79. if(L<=mid) update(t[o].ls,l,mid,L,R,v);
  80. if(R>mid) update(t[o].rs,mid+1,r,L,R,v);
  81. }
  82. int query(int o,int l,int r,int x){
  83. if(l==r || !o) return t[o].x;
  84. if(x<=mid) return t[o].x^query(t[o].ls,l,mid,x);//不用pushup的原因(异或只用异或一遍)
  85. else return t[o].x^query(t[o].rs,mid+1,r,x);
  86. }
  87. } Point,Chain,Front;
  88. //Point:不在链上的点
  89. //Chain:链上的点的更新(以链头的点值为根)
  90. //Front:链头在Chain上的位置
  91. int main()
  92. {
  93. int n,q,op,x,v,ans;
  94. rd(n),rd(q),rd(k);
  95. init();
  96. while(q--){
  97. rd(op),rd(x);
  98. if(op==1){
  99. rd(v);
  100. while(x<=n && pr[lowbit(x)]<pr[k]){
  101. Point.update(root2,1,n,x,x,v);
  102. x+=lowbitv(x);
  103. } //暴力跳
  104. if(x>n) continue;
  105. GetF(x);
  106. root1=Front.query(root3,1,n,fr);
  107. int tmp=root1;Chain.update(root1,1,n,dis,n,v);
  108. //Chain相当于重构了编号,比如说链头为x,则线段树里编号为2的元素实际上是原树状数组编号为x+lowbit(x)的元素
  109. if(!tmp) Front.update(root3,1,n,fr,fr,root1);
  110. } else{
  111. ans=0;
  112. while(x){
  113. if(pr[lowbit(x)]<pr[k]) ans^=Point.query(root2,1,n,x);
  114. else{
  115. GetF(x);
  116. root1=Front.query(root3,1,n,fr);
  117. if(root1) ans^=Chain.query(root1,1,n,dis);
  118. }
  119. x-=lowbitv(x);
  120. }
  121. printf("%d\n",ans);
  122. }
  123. }
  124. }

LOJ#510 北校门外的回忆(找性质+倍增+线段树)的更多相关文章

  1. LOJ 510: 「LibreOJ NOI Round #1」北校门外的回忆

    题目传送门:LOJ #510. 题意简述: 给出一个在 \(K\) 进制下的树状数组,但是它的实现有问题. 形式化地说,令 \(\mathrm{lowbit}(x)\) 为在 \(K\) 进制下的 \ ...

  2. LOJ #2359. 「NOIP2016」天天爱跑步(倍增+线段树合并)

    题意 LOJ #2359. 「NOIP2016」天天爱跑步 题解 考虑把一个玩家的路径 \((x, y)\) 拆成两条,一条是 \(x\) 到 \(lca\) ( \(x, y\) 最近公共祖先) 的 ...

  3. LOJ#510. 「LibreOJ NOI Round #1」北校门外的回忆(线段树)

    题面 传送门 题解 感谢\(@M\_sea\)的代码我总算看懂题解了-- 这个操作的本质就是每次把\(x\)的\(k\)进制最低位乘\(2\)并进位,根据基本同余芝士如果\(k\)是奇数那么最低位永远 ...

  4. LOJ 北校门外的回忆 倍增+线段树

    正解:倍增+线段树 解题报告: 传送门! $umm$这题有个对正解毫无启发的部分分还有个正解,都挺神仙的所以我都写了趴$QAQ$ 先说部分分 可以考虑把$x$向$x+lowbit(x)$连边,然后当$ ...

  5. 51nod 1463 找朋友 (扫描线+线段树)

    1463 找朋友  基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80 难度:5级算法题  收藏  关注 给定: 两个长度为n的数列A .B 一个有m个元素的集合K 询问Q次 每次询 ...

  6. 【NOI P模拟赛】校门外歪脖树上的鸽子(树链剖分)

    题面 2 ≤ n ≤ 2 × 1 0 5 , 1 ≤ m ≤ 2 × 1 0 5 , 1 ≤ l ≤ r ≤ n , 1 ≤ d ≤ 1 0 8 2 ≤ n ≤ 2 × 10^5,1 ≤ m ≤ 2 ...

  7. loj#6029. 「雅礼集训 2017 Day1」市场(线段树)

    题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...

  8. LOJ.6062.[2017山东一轮集训]Pair(Hall定理 线段树)

    题目链接 首先Bi之间的大小关系没用,先对它排序,假设从小到大排 那么每个Ai所能匹配的Bi就是一个B[]的后缀 把一个B[]后缀的匹配看做一条边的覆盖,设Xi为Bi被覆盖的次数 容易想到 对于每个i ...

  9. 51nod 1463 找朋友(线段树+离线处理)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序, ...

随机推荐

  1. [转帖]Windows 10新预览版上线:可直接运行任意安卓APP了

    Windows 10新预览版上线:可直接运行任意安卓APP了 http://www.pcbeta.com/viewnews-80316-1.html 今晨(3月13日),微软面向Fast Ring(快 ...

  2. Linux基础学习笔记1

    MBR分区 主分区: 1-4,一块硬盘最多四个主分区,对主机必须有,主区可以格式化ntfs,存数据: 扩展分区:1-4,一块硬盘最多一个扩展分区,可以没有扩展分区,划分更小的单元,即逻辑分区: 逻辑分 ...

  3. Ehlib(Delphi控件) v9.2.024 D7-XE10.2 免费绿色特别版

    下载地址:https://www.jb51.net/softs/579413.html#downintro2 EHLib是一个DELPHI 下的非常棒的第三方Grid控件,比DELPHI自带的强大许多 ...

  4. vue-cli(vue脚手架)

    vue-cli用于自动生成vue+webpack项目. 安装webpack:npm install webpack -g 检查webpack是否安装成功和版本:webpack -v 如果是webpac ...

  5. 【python练习题】程序8

    #题目:输出 9*9 乘法口诀表. for i in range(1,10): k = '' for j in range(1,i+1): k += '%s * %s = %s '%(i,j,i*j) ...

  6. How to execute a Stored Procedure with Entity Framework Code First

    Recently I worked on a project, which I started as code first and then I forced to switch to Databas ...

  7. BizTalk Server 如何处理大消息

    什么是大消息? 遗憾的是,此问题的答案不而直接与特定的消息大小,绑定,取决于你的 Microsoft 的特定瓶颈 BizTalk Server 系统. 与大消息关联的问题可分为以下几类: 内存不足错误 ...

  8. Nginx split_client模块

    一般用户AB测试根据比例调用指定的接口  默认编译进nginx Syntax: split_clients string $variable { ... } Default: — Context: h ...

  9. 洛谷 P2119 魔法阵

    题目描述 六十年一次的魔法战争就要开始了,大魔法师准备从附近的魔法场中汲取魔法能量. 大魔法师有mm个魔法物品,编号分别为1,2,...,m1,2,...,m.每个物品具有一个魔法值,我们用X_iXi ...

  10. python 模块之-ffmpeg 中文参数对照表

    a) 通用选项 -L license-h 帮助-fromats 显示可用的格式,编解码的,协议的...-f fmt 强迫采用格式fmt-I filename 输入文件-y 覆盖输出文件-t durat ...