[均摊 平衡树 || 线段树] HDU 5634 Rikka with Phi
来源:互联网 发布:nba数据统计排名 编辑:程序博客网 时间:2024/06/05 08:40
用平衡树维护 分析同 [均摊 平衡树 || 线段树] Codeforces 438D #250 (Div. 1) D. The Child and Sequence
#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;typedef long long ll;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++;}inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=1200005;struct node{ int val,sum,lp,rp; int size; ll ans; int clk; node *l,*r,*p,*minv; node(){ } int cnt() { return rp-lp+1; } void newnode(int x,int il,int ir,int ic){ lp=il,rp=ir; size=1; sum=ir-il+1; val=x; ans=(ll)cnt()*val; minv=this; l=r=p=NULL; clk=ic; } void setl(node *x) { l=x; if (x) x->p=this; } void setr(node *x) { r=x; if (x) x->p=this; } void update(){ minv=this; sum=cnt(); size=1; ans=(ll)cnt()*val; if (l) { sum+=l->sum,size+=l->size; ans+=l->ans; if (l->minv->clk<minv->clk) minv=l->minv; } if (r) { sum+=r->sum,size+=r->size; ans+=r->ans; if (r->minv->clk<minv->clk) minv=r->minv; } }}nodes[N],*root;int ncnt;inline int Size(node *x){ return x?x->size:0; }inline int Sum(node *x){ return x?x->sum:0; }inline ll Ans(node *x){ return x?x->ans:0; }inline int ran(){ static int x=31253125; x+=(x<<4)+1; return x&65536;}inline node* Merge(node *A,node *B){ if (!A || !B) return A?A:B; if (ran()){ node *y=Merge(A->r,B); A->setr(y); A->update(); return A; }else{ node *y=Merge(A,B->l); B->setl(y); B->update(); return B; }}typedef pair<node*,node* > Droot;inline Droot Split(node *x,int k){ if (!x) return Droot(NULL,NULL); Droot y; if(Size(x->l)>=k){ y=Split(x->l,k); x->setl(y.second); x->update(); if (y.first) y.first->p=NULL; y.second=x; }else{ y=Split(x->r,k-Size(x->l)-1); x->setr(y.first); x->update(); if (y.second) y.second->p=NULL; y.first=x; } return y;}inline int Find(int k){ node *x=root; int ret=0; while (1){ if (k>Sum(x->l) && k<=Sum(x->l)+x->cnt()) return ret+Size(x->l)+1; if (Sum(x->l)>=k) x=x->l; else k-=Sum(x->l)+x->cnt(),ret+=1+Size(x->l),x=x->r; }}inline node *Findkth(int k){ node *x=root; while (1){ if (k==Size(x->l)+1) return x; Size(x->l)>=k?x=x->l:(k-=Size(x->l)+1,x=x->r); }}inline node *Build(int *a,int l,int r){ if (l>r) return NULL; if (l==r) { nodes[++ncnt].newnode(a[l],l,r,a[l]==1?1<<30:0); return nodes+ncnt; } int mid=(l+r)>>1,t=++ncnt; nodes[t].newnode(a[mid],mid,mid,a[mid]==1?1<<30:0); nodes[t].setl(Build(a,l,mid-1)); nodes[t].setr(Build(a,mid+1,r)); nodes[t].update(); return nodes+t;}int n,a[N];inline void Work(int l,int r){ int lp=Find(l),rp=Find(r); if (lp==rp){ Droot x=Split(root,lp-1); Droot y=Split(x.second,1); node *t=y.first,*a=NULL,*b=NULL; if (t->lp<=l-1) nodes[++ncnt].newnode(t->val,t->lp,l-1,t->clk),a=nodes+ncnt; if (r+1<=t->rp) nodes[++ncnt].newnode(t->val,r+1,t->rp,t->clk),b=nodes+ncnt; t->newnode(t->val,l,r,t->clk); t=Merge(a,Merge(t,b)); root=Merge(x.first,Merge(t,y.second)); return; } Droot x=Split(root,lp-1); Droot y=Split(x.second,1); Droot z=Split(y.second,rp-lp-1); Droot w=Split(z.second,1); node *t=y.first,*h=w.first,*a=NULL,*b=NULL; if (t->lp<=l-1) nodes[++ncnt].newnode(t->val,t->lp,l-1,t->clk),a=nodes+ncnt; t->newnode(t->val,l,t->rp,t->clk); t=Merge(a,t); if (r+1<=h->rp) nodes[++ncnt].newnode(h->val,r+1,h->rp,h->clk),b=nodes+ncnt; h->newnode(h->val,h->lp,r,h->clk); h=Merge(h,b); root=Merge(x.first,Merge(t,Merge(z.first,Merge(h,w.second))));}const int MAXN=1e7+5;const int maxn=1e7;int prime[800005],num;int phi[MAXN];inline void Pre(){ phi[1]=1; for (int i=2;i<=maxn;i++){ if (!phi[i]) prime[++num]=i,phi[i]=i-1; for (int j=1;j<=num && (ll)prime[j]*i<=maxn;j++){ if (i%prime[j]==0)phi[i*prime[j]]=phi[i]*prime[j]; elsephi[i*prime[j]]=phi[i]*phi[prime[j]]; if (i%prime[j]==0)break; } }}int main(){ int Q,order,l,r,w,T; freopen("t.in","r",stdin); freopen("t.out","w",stdout); Pre(); read(T); while (T--){ read(n); read(Q); for (int i=1;i<=n;i++) read(a[i]); root=Build(a,1,n); for (int ti=1;ti<=Q;ti++){ read(order); if (order==3){read(l); read(r);Work(l,r);int lp=Find(l),rp=Find(r);Droot x=Split(root,lp-1);Droot y=Split(x.second,rp-lp+1);printf("%I64d\n",Ans(y.first));root=Merge(x.first,Merge(y.first,y.second)); }else if (order==1){read(l); read(r);Work(l,r);int lp=Find(l),rp=Find(r);Droot x=Split(root,lp-1);Droot y=Split(x.second,rp-lp+1);node *t=y.first,*f;while ((f=t->minv)->clk<ti){ f->val=phi[f->val]; f->clk=f->val==1?1<<30:ti; while (f!=t) f->update(),f=f->p; t->update();}root=Merge(x.first,Merge(y.first,y.second)); }else if (order==2){read(l); read(r); read(w);Work(l,r);int lp=Find(l),rp=Find(r);Droot x=Split(root,lp-1);Droot y=Split(x.second,rp-lp+1);nodes[++ncnt].newnode(w,l,r,w==1?1<<30:ti);root=Merge(x.first,Merge(nodes+ncnt,y.second)); } } ncnt=0; } return 0;}
其实也可以直接上线段树 http://blog.csdn.net/weizhuwyzc000/article/details/50737079
用线段树维护 分析同 [均摊 线段树] UOJ #228. 基础数据结构练习题
0 0
- [均摊 平衡树 || 线段树] HDU 5634 Rikka with Phi
- HDU 5634 Rikka with Phi (线段树)
- HDU 5634 Rikka with Phi(线段树)
- HDU 5634 Rikka with Phi(暴力、线段树)
- HDU 5634-Rikka with Phi(线段树区间更新)
- HDU5634 Rikka with Phi(线段树)
- hdoj 5634 Rikka with Phi 【线段树 + 欧拉】
- HDU 5634 Rikka with Phi(线段树+欧拉函数)
- HDU 5634 Rikka with Phi
- HDU 5634 Rikka with Phi
- HDU 5634 Rikka with Phi
- 【hdu5634】Rikka with Phi(线段树+欧拉函数)
- HDU 5828 Rikka with Sequence(线段树+小优化)
- HDU 5828 Rikka with Sequence(线段树)
- Hdu-5828 Rikka with Sequence(线段树)
- hdu 5828 Rikka with Sequence 【线段树+优化】
- HDU-5828-Rikka with Sequence(线段树)
- 【HDU 5828】Rikka with Sequence(线段树)
- mobile/移动端
- 停下来想一想:你为什么会离开游戏行业?
- vs2012如何运行vs2013和vs2015创建的项目
- float类型做为参数传递过程中出现的问题
- 11.4容器的打印
- [均摊 平衡树 || 线段树] HDU 5634 Rikka with Phi
- DRAMSim2学习1——简介
- c# XML读取创建修改节点,子节点,和值
- 配置nginx+php+mysql遇到的问题
- 【BZOJ 1528】[POI2005]sam-Toy Cars 贪心+堆
- uitextview.text赋值时,输入改变uitextview的值,监听改变状态
- js高级程序设计笔记5---BOM对象
- vue.js的devtools安装
- 网络安全-数据加密算法详解