【纪中集训2019.3.25】芬威克树
题目
描述
第一段代码正确第用\(k\)进制\(BIT\)维护了前缀和;
第二段代码由于写错了\(line \ 4\),所以意义发生了改变;
维护第二段代码执行\(ADD(x,v)\)和\(QUERY(x)\)的答案;
范围
$1 \le n \le 10^9 , 1 \le q \le 2 \times 10^5 , 2 \le k \le 10^5 $ ;
题解
首先不管如何变化,这都是一个树形结构;
但是由于\(n\)较大,所以无法直接支持维护树链;
设\(k = t \times 2 ^ p (t \% 2=1)\) ;
对于\(v = x 2^y (x \% 2=1)\);
- 1.当\(y \ge p\)时,执行ADD时\(v\)的最低位是不会改变的,同时由于\(x\)在\(t\)的意义下有逆元,所以\(v\)至多有一个满足$y\ge p $的儿子,即这些节点形成了很多条链;
- 2.当\(y<p\)时,执行一次加最低位值会让\(y++\),注意有可能最低位变化然后重新来过,但是最多有\(log_k n\)次,即这些点最多向上$log_k n \times p = log_{k} n log_2 k = log_2 n $ 次就会到1中的链上去;
可以暴力\(HASH\)维护\(2\),离散后用\(BIT\)维护\(1\) ;
只需要找到\(1\)中的链的叶子,注意在链上每次的进位是确定的,为对最低位的高一位进1;
链叶子满足\(x\)处于最低位,同时无法退位,所以形如:$ (2x+1) 2^p k^y , (y \ge 0 , 0 \le x \lt \frac{\frac{t}{2^p}-1}{2}) $即可;
可以\(klog \ k\)倍增方便地找到这些位置;
时间复杂度应该是:$k log_2 k + q (log_2 n + log_2 q +loq_2 k ) $ ; ?(似乎和出题人分析的有点不太一样。。。)
orz 租酥雨
#include<bits/stdc++.h> #define pb push_back #define mk make_pair #define fi first #define se second #define ull unsigned long long #define il inline #define rg register using namespace std; const int N=200010,M=31; int n,m,k,MX,A,B,S,cnt,id; struct data{int op,x,y;}Q[N]; int f[N][M],bin[M]; pair<int,int>v1[N]; //map<int,int>mp1;//,mp2; vector<int>vec[N],val[N],v2[N]; ull pw[100]; il char gc(){static char*p1,*p2,s[1000000];if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);return(p1==p2)?EOF:*p1++; } il int rd(){int x=0;char c=gc();while(c<'0'||c>'9')c=gc();while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();return x; } const int sz=123451; struct Hash{int o,hd[sz],nt[N*M],v[N*M],w[N*M];int& operator [](const int&x){int y=x%sz;for(rg int i=hd[y];i;i=nt[i]){if(v[i]==x)return w[i];}nt[++o]=hd[y],hd[y]=o,v[o]=x,w[o]=0;return w[o];} }mp1,mp2; il void init(){int iv2=A+1>>1;for(rg int i=1;i<A;++i){if(i&1)f[i][0]=(ull)i*iv2%A;else f[i][0]=f[i>>1][0];while((f[i][0]&1)==0)f[i][0]>>=1;}for(rg int i=1;i<MX;++i)for(rg int j=0;j<A;++j)f[j][i]=f[f[j][i-1]][i-1]; } il int get(int x,int y){int t=x/k;x%=k;x>>=B;while(x&&((x&1)==0))x>>=1; for(rg int i=0;i<MX;++i)if(bin[i]&t)t^=bin[i],x=f[x][i];x<<=B;x*=pw[y];if(!mp1[x])return mp1[x]=++id;return mp1[x]; } il int inc(int&x,int&y,int c){while(x%c==0&&(x/=c))y++;} il void add(int x,int y,int z){for(;y<=vec[x].size();y+=y&-y)val[x][y]^=z;} il int ask(int x,int y){int re=0;for(;y;y-=y&-y)re^=val[x][y];return re; } il void upd(int x,int y,int z){y=lower_bound(vec[x].begin(),vec[x].end(),y)-vec[x].begin()+1;add(x,y,z); } il int que(int x,int y){if(vec[x].begin()==vec[x].end())return 0;y=lower_bound(vec[x].begin(),vec[x].end(),y+1)-vec[x].begin();return ask(x,y); } char ps[1000000],*pp=ps; void flush(){fwrite(ps,1,pp-ps,stdout);} void push(char x){if(pp==ps+1000000)fwrite(ps,1,1000000,stdout),pp=ps;*pp++=x; } void write(int x){static int sta[N],top;if(!x){push('0');push('\n');return;}while(x)sta[++top]=x%10,x/=10;while(top)push(sta[top--]^'0');push('\n'); } int main(){freopen("fenwick.in","r",stdin);freopen("fenwick.out","w",stdout);n=rd();m=rd();k=rd();for(rg int i=bin[0]=pw[0]=1;i<=30;++i){bin[i]=bin[i-1]<<1;pw[i]=pw[i-1]*k;}inc(A=k,B=0,2);S=(1<<B)-1;MX=log2(n)+1;init();for(rg int i=1,op,t,p;i<=m;++i){Q[i].op=op=rd();if(op&1){Q[i].x=rd(),Q[i].y=rd();inc(p=Q[i].x,t=0,k);while((p%k&S) && (ull)p*pw[t]<=n){v2[i].pb(p*pw[t]);inc(p+=p%k,t,k);}if((ull)p*pw[t]<=n)vec[v1[i].fi=get(p,t)].pb(v1[i].se=p*pw[t]);}else Q[i].x=rd();}for(rg int i=1;i<=id;++i){sort(vec[i].begin(),vec[i].end());unique(vec[i].begin(),vec[i].end());for(int j=0;j<vec[i].size();++j)val[i].pb(0);val[i].pb(0);}for(rg int i=1,x,p,t;i<=m;++i){if(Q[i].op&1){for(int j=0;j<v2[i].size();++j)mp2[v2[i][j]]^=Q[i].y;if(v1[i].fi)upd(v1[i].fi,v1[i].se,Q[i].y);}else{int ans=0;inc(p=Q[i].x,t=0,k);while(p){if((p%k&S)==0)ans^=que(get(p,t),p*pw[t]);else ans^=mp2[p*pw[t]];inc(p-=p%k,t,k);}// printf("%d\n",ans); write(ans);}}flush();return 0; }
转载于:https://www.cnblogs.com/Paul-Guderian/p/10638687.html
【纪中集训2019.3.25】芬威克树相关推荐
- 【纪中集训2019.3.12】Mas的仙人掌
题意: 给出一棵\(n\)个点的树,需要加\(m\)条边,每条边脱落的概率为\(p_{i}\) ,求加入的边在最后形成图中仅在一个简单环上的边数的期望: \(1 \le n \ , m \le 1 ...
- 【纪中集训2019.3.20】铁路
题意 描述 现在有一颗树形状的双向铁路,每条边的行驶时间是\(1\): 给出\(m\)条列车行驶的路径\(s_{i}\to t_{i}\),问列车相遇的对数(无序对): \(i和j\)号列车相遇当且仅 ...
- 【纪中集训2019.3.26】动态半平面交
题目 描述 : 给出强制在线参数\(k\),树的大小\(n\),和每个点的点权\(a_i\); 有\(m\)个询问,每个询问是$u ,d $ 的形式: 表示询问\(u\)为根的子树中,和\(u\)的距 ...
- 【纪中集训2019.3.30】星辰大海
题目 描述 有\(n\)个点\(p_1 ,p_2 , \cdots ,\,p_n\) : 现在\(p_1\)不见了,可能的横纵坐标范围是\([-10^6,10^6]\): 同时需要保证每三 ...
- 【纪中集训2019.3.15】恶熊咆哮
题目 描述 有\(n\)只熊,初始时坐标为\((x_i,y_i)\): 这些熊会按照标号依次吼叫,当第\(i\)只熊吼叫,其他熊会移动: \((x_i,y_i)\)会移动到\((x_i \pm 1,y ...
- 2019寒假纪中集训总结学期总结(流水账)
学期总结 这学期上了初三,学校的初.高中校区对调,我们的班主任也由一个生物老师换成了一个化学老师. 之前的班主任比较年轻,跟我们这群学生有这很好的感情,亦师亦友,陪伴我们度过了几乎没有中考压力的初一. ...
- [2021.8纪中集训Day14]
文章目录 1312. 老曹的忧郁 题目 思路 代码 1313. 老曹骑士 题目 思路 代码 1314. 稳定的数字 题目 思路 代码 封锁阳光大学 题目 题目描述 输入格式 输出格式 输入输出样例 说 ...
- 纪中集训2020.01.13【NOIP普及组】模拟赛C组总结————My First Time Write Summary
纪中集训2020.01.13[NOIP普及组]模拟赛C组总结 题目编号 标题 0 [NOIP普及组模拟]取值( numbers.pas/cpp) 1 [NOIP普及组模拟]数对(pairs.pas/c ...
- 纪中集训2020.01.16【NOIP普及组】模拟赛C组总结+【0.Matrix】分析
纪中集训2020.01.16[NOIP普及组]模拟赛C组总结+[0.Matrix]分析 题目: 0.matrix 1.product 2.binary 3.value 巨佬估分:100+100+40+ ...
最新文章
- DataBase 之 拉链表结构设计
- kafka教程视频百度网盘下载,聊一聊-MySQL-数据库中的那些锁
- 利用jvisualvm分析JVM,进行性能调优
- vivo 2019:关于企业文化如何影响手机企业发展的三个追问
- Java序列化注意事项
- python创建进程的方法_python进程的状态、创建及使用方法详解
- 代码写累了来这看看,笑笑
- Flex接受任意拖拽
- 这几个截图文字识别软件可以自动识别文字
- Gym 10102B 贪心
- STM32MP157移植Qt5.12.10
- 计算机登录界面没有用户显示不出来,win7让administrator账户不出现在登陆界面方法...
- 什么是实验室人员比对人员_实验室人员比对分析方法的讨论
- 【操作系统】知识梳理(十一)多媒体操作系统
- Flink常用算子Transformation介绍
- 域名解析ip地址的过程
- 强化学习《蘑菇书 EasyRL第一章 概览》
- android word分页,控制分页
- 用C实现汉诺塔问题(体现每次移动时方块的位置变化和计算共移动多少次)
- 从SpriteKit看我的游戏人生