题面

传送门

题解

感谢\(@M\_sea\)的代码我总算看懂题解了……

这个操作的本质就是每次把\(x\)的\(k\)进制最低位乘\(2\)并进位,根据基本同余芝士如果\(k\)是奇数那么最低位永远不会变为\(0\),也就是说最低位所在的位置是不变的,并且\(1\)到\(n\)会被分成若干条链,链上我们可以用线段树之类的搞一搞

然而如果\(k\)不是奇数的话事情就会变得比较辣手了……不过我们可以发现对于所有满足\(x=a\times 2^s\)的数,如果\(k=b\times 2^t\)且\(s\geq t\)那么所有的\(x\)依然是能划分成若干条链的……对于那些不在链上的数我们可以直接暴力,复杂度是\(O(\log_2 k\times \log_k n)=O(\log_2 n)\)

然而现在还有一个更加辣手的问题就是对于一个在链上的数我们要如何判断它属于哪条链,因为链的开头可以唯一确定整条链,我们现在的问题就是如何对于每一个数寻找链的开头。我们可以记\(f_{i,j}\)表示最低非\(0\)位上的数字为\(j\),最低非\(0\)位前面的数字是\(2^i\),此时的链的开头是什么,倍增跑一下就可以了。(链的开头必定只有最低非\(0\)位上有数字)

然后没有然后了

//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int K=-1,Z=0;
inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
void print(R int x){
if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++K]=z[Z],--Z);sr[++K]='\n';
}
const int N=2e5+5,M=7e6+5;
struct node;typedef node* ptr;
int f[31][N],n,q,k;map<int,int>tmp;map<pair<int,int>,ptr>rt;
struct node{ptr lc,rc;int s;}e[M],*pp=e;
int find(int x){
int res=x%k;x/=k;while(res&1^1)res>>=1;
for(R int i=0;(1<<i)<=x;++i)if(x>>i&1)res=f[i][res];
return res;
}
void ins(ptr &p,int l,int r,int x,int v){
if(p==NULL)p=++pp;p->s^=v;if(l==r)return;
int mid=(l+r)>>1;
x<=mid?ins(p->lc,l,mid,x,v):ins(p->rc,mid+1,r,x,v);
}
int query(ptr p,int l,int r,int x){
if(p==NULL)return 0;if(l==r)return p->s;
int mid=(l+r)>>1;
if(x<=mid)return query(p->lc,l,mid,x);
return (p->lc==NULL?0:p->lc->s)^query(p->rc,mid+1,r,x);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),q=read(),k=read();
int t=k,bin=k&-k;
while(t&1^1)t>>=1;
for(R int i=1,tt;i<t;i+=2){
tt=i+t;while(tt&1^1)tt>>=1;
f[0][i]=tt;
}
for(R int i=1;(1<<i)<=n;++i)for(R int j=1;j<t;j+=2)f[i][j]=f[i-1][f[i-1][j]];
for(int op,x,v,t;q;--q){
op=read(),x=read(),t=1;
while(x%k==0)x/=k,t*=k;
if(op&1){
v=read();
while(x*t<=n&&(x&bin-1)){
tmp[x*t]^=v,x+=x%k;
while(x%k==0)x/=k,t*=k;
}
if(x*t<=n)ins(rt[make_pair(t,find(x))],1,n,x*t,v);
}else{
int res=0;
while(x){
res^=(x&bin-1?tmp[x*t]:query(rt[make_pair(t,find(x))],1,n,x*t));
x-=x%k;while(x&&x%k==0)x/=k,t*=k;
}
print(res);
}
}
return Ot(),0;
}

最新文章

  1. [LeetCode]444. Sequence Reconstruction
  2. 项目中遇到的关于兄弟controller之间传值的问题解决
  3. 关于C#循环图片GDI+内存不足异常的记录
  4. delphi中break,continue, exit,abort, halt, runerror的异同
  5. Google搜索的几个使用技巧——让你的搜索结果更准确
  6. C# 网卡IP(网上资料整理)
  7. iOS常见文件及程序的启动原理
  8. 『安全科普』WEB安全之渗透测试流程
  9. 转://Oracle打补丁方法论
  10. oracle中数据类型number(m,n)
  11. VS 远程调试 Azure Web App
  12. /usr 的由来及/usr目录结构 [转]
  13. Linux连接字符串
  14. 搜索类网站记录 &amp;&amp; 代理服务器
  15. js 数组删除元素,并获得真实长度
  16. UVAlive6807 T&#250;nel de Rata (最小生成树)
  17. winphone开发环境配置
  18. bzoj2621: [Usaco2012 Mar]Cows in a Skyscraper(状压DP)
  19. shell__常用命令__grep
  20. Android 快捷方式的创建与查询 快捷方式问题大全 获取快捷方式在Launcher数据库中的信息 Failed to find provider info for com.android.la

热门文章

  1. HDU 2897 经典巴什博弈
  2. CSU 1259 bfs找最短路
  3. android studio配置so文件路径
  4. android framework navigationbar自定义
  5. 洛谷 U41571 Agent2
  6. Microsoft Office 2016 for win10 全版本下载+注册激活_Office教程学习网
  7. php-fpm回顾和总结
  8. ovs ml2
  9. Chains (链 )
  10. 第6章1节《MonkeyRunner源代码剖析》Monkey原理分析-事件源-事件源概览