CF633H Fibonacci-ish II(莫队+线段树)
Posted hfctf0210
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF633H Fibonacci-ish II(莫队+线段树)相关的知识,希望对你有一定的参考价值。
温馨提示:本题十分卡常数,我手动开O2才过的。而数据范围不伦不类的n<=30000,常数小的O(n2)居然比O(n√nlogn)跑得快……
考虑插进去一个元素对答案产生的影响。原本数列为Σa[i]f[i],其中1<=i<=n,然后考虑在k位置插入a[0],答案显然是a[1]f[1]+a[2]f[2]+...+a[0]f[k]+a[k]f[k+1]+...+a[n]f[n+1],然后直接区间加斐波那契数显然是不可能的。这时候要向后转移斐波那契数列,(a,b)->(a+b,a)->(2a+b,a+b)->(3a+2b,2a+b)->……系数始终是斐波那契数。
删除时向前转移?系数可以和斐波那契数一起直接求。
我是开O2、O3、Ofast优化才过的,如果能正常过可能会换成常数较小的code吧
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #pragma GCC optimize("inline") #pragma GCC optimize("-fgcse") #pragma GCC optimize("-fgcse-lm") #pragma GCC optimize("-fipa-sra") #pragma GCC optimize("-ftree-pre") #pragma GCC optimize("-ftree-vrp") #pragma GCC optimize("-fpeephole2") #pragma GCC optimize("-ffast-math") #pragma GCC optimize("-fsched-spec") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("-falign-jumps") #pragma GCC optimize("-falign-loops") #pragma GCC optimize("-falign-labels") #pragma GCC optimize("-fdevirtualize") #pragma GCC optimize("-fcaller-saves") #pragma GCC optimize("-fcrossjumping") #pragma GCC optimize("-fthread-jumps") #pragma GCC optimize("-funroll-loops") #pragma GCC optimize("-fwhole-program") #pragma GCC optimize("-freorder-blocks") #pragma GCC optimize("-fschedule-insns") #pragma GCC optimize("inline-functions") #pragma GCC optimize("-ftree-tail-merge") #pragma GCC optimize("-fschedule-insns2") #pragma GCC optimize("-fstrict-aliasing") #pragma GCC optimize("-fstrict-overflow") #pragma GCC optimize("-falign-functions") #pragma GCC optimize("-fcse-skip-blocks") #pragma GCC optimize("-fcse-follow-jumps") #pragma GCC optimize("-fsched-interblock") #pragma GCC optimize("-fpartial-inlining") #pragma GCC optimize("no-stack-protector") #pragma GCC optimize("-freorder-functions") #pragma GCC optimize("-findirect-inlining") #pragma GCC optimize("-frerun-cse-after-loop") #pragma GCC optimize("inline-small-functions") #pragma GCC optimize("-finline-small-functions") #pragma GCC optimize("-ftree-switch-conversion") #pragma GCC optimize("-foptimize-sibling-calls") #pragma GCC optimize("-fexpensive-optimizations") #pragma GCC optimize("-funsafe-loop-optimizations") #pragma GCC optimize("inline-functions-called-once") #pragma GCC optimize("-fdelete-null-pointer-checks") #include<bits/stdc++.h> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 using namespace std; typedef pair<int,int>pii; const int N=30086; struct nodeint l,r,id;q[N]; int n,m,B,Q,mod,f[N],g[N],vis[N],a[N],w[N],sz[N<<2],lazy[N<<2],c[N<<2][2],ans[N]; pii p[N]; bool cmp(node a,node b)return (a.l-1)/B==(b.l-1)/B?a.r<b.r:a.l<b.l; void pushup(int rt) sz[rt]=sz[rt<<1]+sz[rt<<1|1]; c[rt][0]=(c[rt<<1][0]+c[rt<<1|1][0])%mod; c[rt][1]=(c[rt<<1][1]+c[rt<<1|1][1])%mod; void add(int rt,int k) lazy[rt]+=k; int a=c[rt][0],b=c[rt][1]; if(k>0)c[rt][0]=(1ll*a*f[k+1]+1ll*b*f[k])%mod,c[rt][1]=(1ll*a*f[k]+1ll*b*f[k-1])%mod; else k=-k,c[rt][0]=(1ll*a*g[k-1]+1ll*b*g[k])%mod,c[rt][1]=(1ll*a*g[k]+1ll*b*g[k+1])%mod; void pushdown(int rt)if(lazy[rt])add(rt<<1,lazy[rt]),add(rt<<1|1,lazy[rt]),lazy[rt]=0; void update(int k,int v,int d,int l,int r,int rt) if(l==r) if(v==-1)c[rt][0]=c[rt][1]=sz[rt]=0; else c[rt][0]=1ll*f[v]*a[l]%mod,c[rt][1]=1ll*f[v-1]*a[l]%mod,sz[rt]=1; return; pushdown(rt); int mid=l+r>>1; if(k<=mid)update(k,v,d,lson),add(rt<<1|1,d); else update(k,v+(v!=-1)*sz[rt<<1],d,rson); pushup(rt); void add(int x) if(!x)return; if(!vis[x])update(x,1,1,1,m,1); vis[x]++; void del(int x) if(!x)return; vis[x]--; if(!vis[x])update(x,-1,-1,1,m,1); int main() scanf("%d%d",&n,&mod),B=170; f[1]=f[2]=1; for(int i=3;i<=n+1;i++)f[i]=(f[i-1]+f[i-2])%mod; g[1]=1,g[2]=mod-1; for(int i=3;i<=n+1;i++)g[i]=(g[i-2]-g[i-1]+mod)%mod; for(int i=1,x;i<=n;i++)scanf("%d",&x),p[i]=pii(x,i); sort(p+1,p+n+1); for(int i=1,lst=1e9+7;i<=n;i++) if(lst!=p[i].first)lst=p[i].first,a[++m]=lst%mod; w[p[i].second]=m; scanf("%d",&Q); if(mod==1)while(Q--)puts("0");return 0; for(int i=1;i<=Q;i++)scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+Q+1,cmp); for(int i=1,l=0,r=0;i<=Q;i++) while(r<q[i].r)add(w[++r]); while(r>q[i].r)del(w[r--]); while(l<q[i].l)del(w[l++]); while(l>q[i].l)add(w[--l]); ans[q[i].id]=c[1][0]; for(int i=1;i<=Q;i++)printf("%d\n",ans[i]);
以上是关于CF633H Fibonacci-ish II(莫队+线段树)的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces - 633H :Fibonacci-ish II(莫对+线段树)(占位)
[莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II
CF940F Machine Learning (带修改莫队)