【Codeforces633H】Fibonacci-ish II
来源:互联网 发布:那个软件可以套花呗 编辑:程序博客网 时间:2024/05/21 14:06
这题显然需要莫队,然后我就想着用非旋转
#include <bits/stdc++.h>#define gc getchar()#define ll long long#define N 30009#define rd(x) ((rand()*23333+rand())%(x))using namespace std;int n,mod,a[N],f[N],Q,lim,pos[N],Ans[N],now[N];map<int,int> mp;struct qry{ int l,r,id; bool operator <(const qry &rhs) const { return pos[l]<pos[rhs.l]||pos[l]==pos[rhs.l]&&r<rhs.r; }}q[N];struct Treap{ struct node { node *lson,*rson; int key,val,sum1,sum2,add,num,size; node(int x,int y) { add=0,num=y; sum2=(ll)x*f[y-1]%mod; val=x; sum1=(ll)x*f[y]%mod; key=rd(1000000000); lson=rson=NULL; size=1; } }; typedef node * pnode; pnode root,L,R,rest; void init() { root=NULL; } void up(pnode now) { now->sum1=(ll)now->val%mod*f[now->num]%mod; if (now->lson) now->sum1+=now->lson->sum1; now->sum1%=mod; if (now->rson) now->sum1+=now->rson->sum1; now->sum1%=mod; now->sum2=(ll)now->val%mod*f[now->num-1]%mod; if (now->lson) now->sum2+=now->lson->sum2; now->sum2%=mod; if (now->rson) now->sum2+=now->rson->sum2; now->sum2%=mod; now->size=1; if (now->lson) now->size+=now->lson->size; if (now->rson) now->size+=now->rson->size; } void down(pnode now) { if (now->add>0) { if (now->lson) { now->lson->add+=now->add; now->lson->num+=now->add; int t1=now->lson->sum1,t2=now->lson->sum2; now->lson->sum1=((ll)f[now->add+1]*t1%mod+(ll)f[now->add]*t2%mod)%mod; now->lson->sum2=((ll)f[now->add]*t1%mod+(ll)f[now->add-1]*t2%mod)%mod; } if (now->rson) { now->rson->add+=now->add; now->rson->num+=now->add; int t1=now->rson->sum1,t2=now->rson->sum2; now->rson->sum1=((ll)f[now->add+1]*t1%mod+(ll)f[now->add]*t2%mod)%mod; now->rson->sum2=((ll)f[now->add]*t1%mod+(ll)f[now->add-1]*t2%mod)%mod; } now->add=0; } if (now->add<0) { if (now->lson) { now->lson->add+=now->add; now->lson->num+=now->add; int t1=now->lson->sum1,t2=now->lson->sum2; now->lson->sum1=((ll)f[-now->add-1]*t1%mod-(ll)f[-now->add]*t2%mod+mod)%mod; if ((-now->add)&1) now->lson->sum1=(mod-now->lson->sum1)%mod; now->lson->sum2=((ll)f[-now->add+1]*t2%mod-(ll)f[-now->add]*t1%mod+mod)%mod; if ((-now->add)&1) now->lson->sum2=(mod-now->lson->sum2)%mod; } if (now->rson) { now->rson->add+=now->add; now->rson->num+=now->add; int t1=now->rson->sum1,t2=now->rson->sum2; now->rson->sum1=((ll)f[-now->add-1]*t1%mod-(ll)f[-now->add]*t2%mod+mod)%mod; if ((-now->add)&1) now->rson->sum1=(mod-now->rson->sum1)%mod; now->rson->sum2=((ll)f[-now->add+1]*t2%mod-(ll)f[-now->add]*t1%mod+mod)%mod; if ((-now->add)&1) now->rson->sum2=(mod-now->rson->sum2)%mod; } now->add=0; } } pnode merge(pnode L,pnode R) { if (!L) return R; if (!R) return L; if (L->key>R->key) { down(L); L->rson=merge(L->rson,R); up(L); return L; } else { down(R); R->lson=merge(L,R->lson); up(R); return R; } } void split(pnode now,int val,pnode &L,pnode &R) { if (!now) { L=R=NULL; return; } down(now); if (val<=now->val) { split(now->lson,val,L,now->lson); R=now; up(R); return; } else { split(now->rson,val,now->rson,R); L=now; up(L); return; } } void ins(int x) { split(root,x,L,R); if (R) { R->add++; R->num++; int t=(R->sum1+R->sum2)%mod; R->sum2=R->sum1; R->sum1=t; } root=merge(L,new node(x,L?(L->size+1):1)); root=merge(root,R); } void del(int x) { split(root,x,L,R); split(R,x+1,rest,R); if (R) { R->add--; R->num--; int t=(R->sum1-R->sum2+mod)%mod; R->sum1=R->sum2; R->sum2=t; } root=merge(L,R); }}tr;int read(){ int x=1; char ch; while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1; int s=ch-'0'; while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0'; return s*x;}void Insert(int x){ tr.ins(x);}void Delete(int x){ tr.del(x);}void add(int x){ if (!mp[x]) Insert(x); mp[x]++;}void del(int x){ mp[x]--; if (!mp[x]) Delete(x);}int get_Ans(){ return tr.root->sum1;}int main(){ n=read(),mod=read(); //n=30000,mod=30000; for (int i=1;i<=n;i++) a[i]=read(); //a[i]=i; f[0]=0,f[1]=f[2]=1; for (int i=3;i<=n;i++) f[i]=(f[i-1]+f[i-2])%mod; Q=read(); //Q=30000; for (int i=1;i<=Q;i++) q[i].l=read(),q[i].r=read(),q[i].id=i; //q[i].l=rand()%n+1,q[i].r=q[i].l+(rand()%(n-q[i].l+1)),q[i].id=i; lim=(int)sqrt(n); for (int i=1;i<=n;i++) pos[i]=i/lim+1; sort(q+1,q+Q+1); tr.init(); int l=1,r=0; for (int i=1;i<=Q;i++) { while (r<q[i].r) add(a[++r]); while (l>q[i].l) add(a[--l]); while (r>q[i].r) del(a[r--]); while (l<q[i].l) del(a[l++]); Ans[q[i].id]=get_Ans(); //cout<<Ans[q[i].id]<<" "<<Get_Ans()<<endl; } for (int i=1;i<=Q;i++) printf("%d\n",Ans[i]); return 0;}
然后听说这道题可以线段树,,然后听说
所以果断水。
#include <bits/stdc++.h>#define gc getchar()#define ll long long#define N 30009#define rd(x) ((rand()*23333+rand())%(x))using namespace std;int n,mod,a[N],f[N],Q,lim,pos[N],Ans[N],now[N];map<int,int> mp;struct qry{ int l,r,id; bool operator <(const qry &rhs) const { return pos[l]<pos[rhs.l]||pos[l]==pos[rhs.l]&&r<rhs.r; }}q[N];struct Treap{ struct node { node *lson,*rson; int key,val,sum1,sum2,add,num,size; node(int x,int y) { add=0,num=y; sum2=(ll)x*f[y-1]%mod; val=x; sum1=(ll)x*f[y]%mod; key=rd(1000000000); lson=rson=NULL; size=1; } }; typedef node * pnode; pnode root,L,R,rest; void init() { root=NULL; } void up(pnode now) { now->sum1=(ll)now->val%mod*f[now->num]%mod; if (now->lson) now->sum1+=now->lson->sum1; now->sum1%=mod; if (now->rson) now->sum1+=now->rson->sum1; now->sum1%=mod; now->sum2=(ll)now->val%mod*f[now->num-1]%mod; if (now->lson) now->sum2+=now->lson->sum2; now->sum2%=mod; if (now->rson) now->sum2+=now->rson->sum2; now->sum2%=mod; now->size=1; if (now->lson) now->size+=now->lson->size; if (now->rson) now->size+=now->rson->size; } void down(pnode now) { if (now->add>0) { if (now->lson) { now->lson->add+=now->add; now->lson->num+=now->add; int t1=now->lson->sum1,t2=now->lson->sum2; now->lson->sum1=((ll)f[now->add+1]*t1%mod+(ll)f[now->add]*t2%mod)%mod; now->lson->sum2=((ll)f[now->add]*t1%mod+(ll)f[now->add-1]*t2%mod)%mod; } if (now->rson) { now->rson->add+=now->add; now->rson->num+=now->add; int t1=now->rson->sum1,t2=now->rson->sum2; now->rson->sum1=((ll)f[now->add+1]*t1%mod+(ll)f[now->add]*t2%mod)%mod; now->rson->sum2=((ll)f[now->add]*t1%mod+(ll)f[now->add-1]*t2%mod)%mod; } now->add=0; } if (now->add<0) { if (now->lson) { now->lson->add+=now->add; now->lson->num+=now->add; int t1=now->lson->sum1,t2=now->lson->sum2; now->lson->sum1=((ll)f[-now->add-1]*t1%mod-(ll)f[-now->add]*t2%mod+mod)%mod; if ((-now->add)&1) now->lson->sum1=(mod-now->lson->sum1)%mod; now->lson->sum2=((ll)f[-now->add+1]*t2%mod-(ll)f[-now->add]*t1%mod+mod)%mod; if ((-now->add)&1) now->lson->sum2=(mod-now->lson->sum2)%mod; } if (now->rson) { now->rson->add+=now->add; now->rson->num+=now->add; int t1=now->rson->sum1,t2=now->rson->sum2; now->rson->sum1=((ll)f[-now->add-1]*t1%mod-(ll)f[-now->add]*t2%mod+mod)%mod; if ((-now->add)&1) now->rson->sum1=(mod-now->rson->sum1)%mod; now->rson->sum2=((ll)f[-now->add+1]*t2%mod-(ll)f[-now->add]*t1%mod+mod)%mod; if ((-now->add)&1) now->rson->sum2=(mod-now->rson->sum2)%mod; } now->add=0; } } pnode merge(pnode L,pnode R) { if (!L) return R; if (!R) return L; if (L->key>R->key) { down(L); L->rson=merge(L->rson,R); up(L); return L; } else { down(R); R->lson=merge(L,R->lson); up(R); return R; } } void split(pnode now,int val,pnode &L,pnode &R) { if (!now) { L=R=NULL; return; } down(now); if (val<=now->val) { split(now->lson,val,L,now->lson); R=now; up(R); return; } else { split(now->rson,val,now->rson,R); L=now; up(L); return; } } void ins(int x) { split(root,x,L,R); if (R) { R->add++; R->num++; int t=(R->sum1+R->sum2)%mod; R->sum2=R->sum1; R->sum1=t; } root=merge(L,new node(x,L?(L->size+1):1)); root=merge(root,R); } void del(int x) { split(root,x,L,R); split(R,x+1,rest,R); if (R) { R->add--; R->num--; int t=(R->sum1-R->sum2+mod)%mod; R->sum1=R->sum2; R->sum2=t; } root=merge(L,R); }}tr;int read(){ int x=1; char ch; while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1; int s=ch-'0'; while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0'; return s*x;}void Insert(int x){ tr.ins(x);}void Delete(int x){ tr.del(x);}void add(int x){ if (!mp[x]) Insert(x); mp[x]++;}void del(int x){ mp[x]--; if (!mp[x]) Delete(x);}int get_Ans(){ return tr.root->sum1;}int main(){ n=read(),mod=read(); //n=30000,mod=30000; for (int i=1;i<=n;i++) a[i]=read(); //a[i]=i; f[0]=0,f[1]=f[2]=1; for (int i=3;i<=n;i++) f[i]=(f[i-1]+f[i-2])%mod; Q=read(); //Q=30000; for (int i=1;i<=Q;i++) q[i].l=read(),q[i].r=read(),q[i].id=i; //q[i].l=rand()%n+1,q[i].r=q[i].l+(rand()%(n-q[i].l+1)),q[i].id=i; lim=(int)sqrt(n); for (int i=1;i<=n;i++) pos[i]=i/lim+1; sort(q+1,q+Q+1); tr.init(); int l=1,r=0; for (int i=1;i<=Q;i++) { while (r<q[i].r) add(a[++r]); while (l>q[i].l) add(a[--l]); while (r>q[i].r) del(a[r--]); while (l<q[i].l) del(a[l++]); Ans[q[i].id]=get_Ans(); //cout<<Ans[q[i].id]<<" "<<Get_Ans()<<endl; } for (int i=1;i<=Q;i++) printf("%d\n",Ans[i]); return 0;}
阅读全文
0 0
- 【Codeforces633H】Fibonacci-ish II
- Manthan, Codefest 16 H. Fibonacci-ish II (暴力)
- 二分 Codeforces633D Fibonacci-ish
- 【CF633D】Fibonacci-ish
- Codeforces 633H. Fibonacci-ish II (Mo's Algorithm(莫队算法) + 线段树 + 离散化)
- [莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II
- codeforces633D Fibonacci-ish map容器
- Codeforces 633D Fibonacci-ish(搜索)
- Codeforces 633D Fibonacci-ish 【暴力递归】
- Codeforces 633D Fibonacci-ish(暴力)
- CodeForces - 633D Fibonacci-ish (map&暴力)
- Manthan, Codefest 16 D. Fibonacci-ish
- Manthan, Codefest 16-D. Fibonacci-ish
- Codeforces 633D Fibonacci-ish 数学+暴力
- CodeForces 633 D.Fibonacci-ish(枚举)
- Manthan, Codefest 16 D. Fibonacci-ish(暴力、规律)
- Manthan, Codefest 16 633D Fibonacci-ish(脑洞+stl)
- Manthan, Codefest 16 D. Fibonacci-ish(暴力)
- 完美解决Error:Execution failed for task ':APP:transformClassesWithDexForDebug'...问题
- shell script循环遍历字符串数组
- JPA project Change Event Handler问题解决
- Integer.toHexString(b & 0xff)理解以及& 0xff什么意思
- vue的“$index” is undefined错误
- 【Codeforces633H】Fibonacci-ish II
- tornado 简单的web服务
- ionic select元素安卓真机上点击无效的解决方案
- button的样式在浏览器上的兼容性
- 爬虫基础 -- pyquery
- python ztree 异步加载
- 认识Struts2的拦截器
- HDU4635 Strongly connected (tarjan)
- 数据库——purge和drop的区别