正题

题目链接:https://loj.ac/p/510


题目大意

给出一个代码

function add(x,v)while x <= n dos[x] = s[x] xor vx = x + lowbit(x) //注意,这里是 lowbit,这也是两份代码唯一的区别end while
end functionfunction query(x)ans = 0while x > 0 doans = ans xor s[x]x = x - lowbit(x)end whilereturn ans
end function

其中lowbit(x)\text{lowbit(x)}lowbit(x)表示xxx在KKK进制下最低非零位的值。

现在给出n,q,Kn,q,Kn,q,K,qqq次调用add(x,v)add(x,v)add(x,v)或者query(x)query(x)query(x)。

要求输出每次query(x)query(x)query(x)调用的值。

1≤n≤109,2≤q,K≤2×1051\leq n\leq 10^9,2\leq q,K\leq 2\times 10^51≤n≤109,2≤q,K≤2×105


解题思路

注意到询问的时候我们是可以一位一位的做的,主要是修改的时候。

我们先默认最低非零位就是个位,那么相当于每次x=x+x%Kx=x+x\% Kx=x+x%K直到x∣Kx|Kx∣K,如果只考虑个位的情况,也可以视为每次x=2x%Kx=2x\% Kx=2x%K。

首先每个数只有两种到达它的情况,一个是x2\frac{x}{2}2x​,另一个是x+K2\frac{x+K}{2}2x+K​,那么如果KKK是奇数的话,这两个中恰好有一个是整数,也就是每个数字的入边都是111,出边也是111,所以最终图肯定会形成若干个环。

那么考虑KKK不是奇数的情况,如果xxx的222质因子个数不少于KKK的,那么它们则可以表示为x2p\frac{x}{2^p}2px​和K2p\frac{K}{2^p}2pK​,这样的话KKK又是奇数了,也会构成环。

否则xxx一直乘二直到质因子个数不少于KKK,也就是说这种情况走不超过log⁡K\log KlogK步就一定能到达一个环或者000。

那么我们就是先分位计算,最低位不在环上就暴力跳,在环上就考虑维护。

现在主要是环上怎么维护的问题,同一个最低位上,对于一个修改xyxyxy(个位是yyy,剩下的位是xxx),会影响一个询问x′y′x'y'x′y′的条件。

我们需要找到一个不关于这些点的个位的条件,那么我们就考虑对于每个环定义一个点作为环头,然后所有的操作询问都移动到环头上搞。

然后我们把每个修改拆成修改位置到环头一段和从环头开始不停绕环的一段,

那么第一个的一个限制是询问位置要在它后面并且它们都反着退到环头后值相等,可以用线段树维护位置关系。

第二个先把询问倒着移动到环头,那么限制就是它们对于环上进位次数和的余数相等并且询问的值大于修改的值,可以用权值线段树维护。

时间复杂度:O(Klog⁡2n)O(K\log^2 n)O(Klog2n)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define mp(x,y) make_pair(x,y)
using namespace std;
const int N=2e5+10,M=N<<7;
int n,q,K,cnt,lg[N],id[N],sum[N],noe[N],dis[N],len[N];
map<pair<int,int> ,int>rt[40],Rt[40];
map<int,int> g;
struct SegTree{int cnt,w[M],ls[M],rs[M];void Change(int &x,int L,int R,int pos,int val){if(pos<L||pos>R)return;if(!x)x=++cnt;w[x]^=val;if(L==R)return;int mid=(L+R)>>1;if(pos<=mid)Change(ls[x],L,mid,pos,val);else Change(rs[x],mid+1,R,pos,val);return;}int Ask(int x,int L,int R,int l,int r){r=min(r,R);l=max(l,L);if(l>r||!w[x])return 0;if(L==l&&R==r)return w[x];int mid=(L+R)>>1;if(r<=mid)return Ask(ls[x],L,mid,l,r);if(l>mid)return Ask(rs[x],mid+1,R,l,r);return Ask(ls[x],L,mid,l,mid)^Ask(rs[x],mid+1,R,mid+1,r);}
}T;
void dfs(int x,int pos,int one,int fr){if(id[x]){sum[fr]=one;return;}noe[x]=one;id[x]=fr;dis[x]=pos;len[fr]++;dfs(x*2%K,pos+1,one+(x*2>=K),fr);return;
}
int main()
{scanf("%d%d%d",&n,&q,&K);for(int i=1;i<=K;i++)if(i%2==0)lg[i]=lg[i/2]+1;for(int i=1;i<K;i++)if(lg[i]>=lg[K]&&!id[i])++cnt,dfs(i,0,0,cnt);while(q--){int op;scanf("%d",&op);if(op==1){int x,w,i=0,pw=1;scanf("%d%d",&x,&w);while(x*pw<=n){int p=x%K,y=x/K;while(p&&x*pw<=n){if(lg[p]>=lg[K]){T.Change(rt[i][mp(id[p],y-noe[p])],0,len[id[p]]-1,dis[p],w);T.Change(Rt[i][mp(id[p],(y-noe[p]+sum[id[p]])%sum[id[p]])],0,n/pw/K,y+sum[id[p]]-noe[p],w);x=0;break;}else g[x*pw]^=w,x+=x%K,p=x%K,y=x/K;}if(!x||x*pw>n)break;x=x/K;pw=pw*K;i++;}}else{int x;scanf("%d",&x);int i=0,pw=1,ans=0;while(x){int p=x%K,y=x/K;if(p!=0){if(lg[p]>=lg[K]){ans^=T.Ask(rt[i][mp(id[p],y-noe[p])],0,len[id[p]]-1,0,dis[p]);ans^=T.Ask(Rt[i][mp(id[p],(y-noe[p]+sum[id[p]])%sum[id[p]])],0,n/pw/K,0,y-noe[p]);}else ans^=g[x*pw];}x/=K;i++;pw=pw*K;}printf("%d\n",ans);}}return 0;
}

Loj#510-「LibreOJ NOI Round #1」北校门外的回忆【线段树】相关推荐

  1. LOJ #510. 「LibreOJ NOI Round #1」北校门外的回忆(倍增+动态开点线段树)

    题目 这个题是一个精彩的分析性质区间离散的问题 真的详细 维护链真的一绝. LOJ\rm LOJLOJ最短ACCode\rm AC \ CodeAC Code #include<bits/std ...

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

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

  3. LOJ #573. 「LibreOJ NOI Round #2」单枪匹马 线段树

    $f$ 函数暴力计算的话是 $O(n)$ 的(用一个 $\frac{x}{y}$ 来保存每一步计算结果,然后依次合并) 我们将一段区间的结果写成 $\frac{ax+by}{cx+dy}$ 的形式,初 ...

  4. 「LibreOJ NOI Round #2」不等关系 (dp+NTT分治)

    description 戳我看题目哦 solution 有一道非常相似的题目 一棵树,每条边限制两个端点的大小关系(限制 a[u]>a[v]a[u]>a[v]a[u]>a[v] 或 ...

  5. 【LOJ574】「LibreOJ NOI Round #2」黄金矿工

    [题目链接] 点击打开链接 [思路要点] 可参考 官方题解 . 以下为笔者个人的见解,方便起见,下称矿工为老鼠,金矿为洞. 我们可以对洞的权值加上深度,老鼠的权值减去深度,从而不需要考虑树的边权. 考 ...

  6. 【LOJ573】「LibreOJ NOI Round #2」单枪匹马(矩阵乘法)

    传送门 题解: 注意到分子分母每次无非就是交换位置然后分母加上分子的若干倍. 把这个转移写成矩阵的形式,求个逆,维护一下矩阵和矩阵的逆的前缀积就行了. 代码: #include<bits/std ...

  7. 「LibreOJ NOI Round #2」单枪匹马

    题目 通过这道题成功发现我不会矩乘 答案是一个连分数,看起来不像是一般的数据结构能做的样子,设\(x_{l,r},y_{l,r}\)分别表示\([l,r]\)询问的分子和分母 于是有 \[\frac{ ...

  8. 【LOJ573】「LibreOJ NOI Round #2」单枪匹马

    [题目链接] 点击打开链接 [思路要点] 见 官方题解 .(反正也是我写的) 时间复杂度 O(N+M)O(N+M)O(N+M) . [代码] #include<bits/stdc++.h> ...

  9. LOJ#538. 「LibreOJ NOIP Round #1」数列递推

    description sosusosu 虐爆 OI 之后成为了一名文化课选手.一天,他做作业碰到了一堆数列问题,每道题给出的数列都是以下形式: 给定一个下标从000开始,无限长的整数列ai{a_{i ...

最新文章

  1. 疲劳驾驶样本集_欧洲要求,2022年开始新车必须配备DMS(防疲劳预警)系统
  2. MySQL的主从复制
  3. 联发科MTK工程模式(中文对照版本)和测试模式指令
  4. office365打开服务器文件出错,Microsoft Office 365个人版打开显示错误
  5. 【LeetCode】18. 4Sum 四数之和
  6. 程序性能优化之编译器篇(Racoon)
  7. HDU 1867(kmp应用)
  8. 黑寡妇(BWO)优化算法(Matlab代码实现)
  9. [转]Unity 打包快手
  10. web安全[网易白帽子课程笔记+体会]-03web安全工具
  11. Webpack——ES6转ES5
  12. 【181101】VC++电子地图绘制工具源代码
  13. SEO工作,不要三人成虎!
  14. Cloudera Manager安装之Cloudera Manager安装前准备(CentOS6.5)(一)
  15. [Qt]QMainWindow
  16. 一种无痕过渡下拉刷新控件的实现思路
  17. Django Template 网页模板(五)
  18. 嵌入式数据库知识概括
  19. ConfluxScan 验证合约详解
  20. 高考英语口试计算机,重庆高考英语口试怎么考

热门文章

  1. 极客日报第 22 期:新荣耀员工现金补偿最高可拿 N+5;酷派员工积极提交补丁获 Linus 关注,获公司10万股期权奖励
  2. HTML语言特殊字符对照表(ISO Latin-1字符集)
  3. 转移到ios下载安卓_转移到ios下载官方app-转移到ios手机版v3.0.1 安卓版 - 极光下载站...
  4. matlab 海塞矩阵 多元函数求极值,基于Hessian矩阵的多元函数极值问题.pdf
  5. Python - RC4 算法
  6. JavaWeb与Tomcat简介
  7. 一文搞懂JS中的赋值·浅拷贝·深拷贝
  8. Conditional Structure Generation throughGraph Variational Generative Adversarial Nets 论文阅读
  9. Windows下网络编程及多线程模型
  10. 狂神说Java的多线程课程总结