[BZOJ 2038]小Z的袜子 莫队(Mo's Algorithm)模板题
2017-06-11 10:57
232 查看
今天总算撸懂了莫队
贴一个模板题代码 小Z的袜子
自己写了一种比较舒服的区间增减
如果当前已知区间的左端点小于询问区间的左端点,则需要将当前已知区间的左端点向右移。每次右移之前都需要先减去当前点对答案的影响。
如果当前已知区间的左端点大于询问区间的左端点,则需要将当前已知区间的左端点向左移。每次左移之后都需要再加上当前点对答案的影响。
右区间同理
Modify操作的实现步骤:
在答案中减去当前状态未被修改时对答案的贡献,进行修改操作后,再在答案中加上该状态被修改后对答案的新计算出的贡献。
贴一个模板题代码 小Z的袜子
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int max_n=500005; int n,m,size; int hose[max_n],pos[max_n]; long long tot[max_n]; class Query { public: int l;int r;int id;long long a,b; }q[max_n]; bool cmp(Query a,Query b) { if(pos[a.l]==pos[b.l]) return a.r<b.r; else return pos[a.l]<pos[b.l]; } int L=1,R=0; long long ans=0; void change(int val,int cl) { ans-=tot[cl]*tot[cl]; tot[cl]+=val; ans+=tot[cl]*tot[cl]; } long long gcd(long long a,long long b) { return b==0?a:gcd(b,a%b); } void work() { for(register int i=1;i<=m;i++) { if(q[i].l==q[i].r) q[i].a=0,q[i].b=1; else { while(L<q[i].l) change(-1,hose[L]),L++; while(L>q[i].l) L--,change(1,hose[L]); while(R<q[i].r) R++,change(1,hose[R]); while(R>q[i].r) change(-1,hose[R]),R--; q[i].a=ans-(q[i].r-q[i].l+1);q[i].b=(long long)(q[i].r-q[i].l+1)*(q[i].r-q[i].l); long long k=gcd(q[i].a,q[i].b); q[i].a/=k;q[i].b/=k; } } } bool outcmp (Query a ,Query b) { return a.id<b.id;} void output() { sort(q+1,q+1+m,outcmp); for(register int i=1;i<=m;i++) printf("%lld/%lld\n",q[i].a,q[i].b); } int main() { scanf("%d%d",&n,&m); for(register int i=1;i<=n;i++) scanf("%d",&hose[i]); size=(int)sqrt(n+0.5); for(register int i=0;i<=n;i++) pos[i]=i/size; for(register int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+1+m,cmp); work(); output(); return 0; }
自己写了一种比较舒服的区间增减
如果当前已知区间的左端点小于询问区间的左端点,则需要将当前已知区间的左端点向右移。每次右移之前都需要先减去当前点对答案的影响。
如果当前已知区间的左端点大于询问区间的左端点,则需要将当前已知区间的左端点向左移。每次左移之后都需要再加上当前点对答案的影响。
右区间同理
while(L<Q.L) Modify(L,-1),L++; while(L>Q.L) L--,Modify(L,1); while(R<Q.R) R++,Modify(R,1); while(R>Q.R) Modify(R,-1),R--;
Modify操作的实现步骤:
在答案中减去当前状态未被修改时对答案的贡献,进行修改操作后,再在答案中加上该状态被修改后对答案的新计算出的贡献。
相关文章推荐
- BZOJ - 2038: 小Z的袜子(hose) 莫队算法 模板
- BZOJ 2038 小Z的袜子 莫队算法(模板题)
- bzoj 2038 小Z的袜子 莫队模板
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)|分块|莫队算法
- BZOJ 2038([2009国家集训队]小Z的袜子(hose)-莫队算法序列)
- 莫队算法—【清ojA1206】【bzoj2038】小Z的袜子
- [国家集训队][bzoj2038] 小Z的袜子 [莫队]
- 小Z的袜子(hose) - bzoj 2038 莫队算法
- BZOJ 2038 小Z的袜子 莫队
- 浅谈莫队 BZOJ 2038 小Z的袜子 (莫队 分块)
- BZOJ2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)
- bzoj 2038 小Z的袜子 莫队
- BZOJ 2038 小Z的袜子(hose) 莫队算法
- bzoj 2038: [2009国家集训队]小Z的袜子(hose)(莫队算法)
- BZOJ-2038-[2009国家集训队]小Z的袜子(hose)(莫队)
- BZOJ 2038 小Z的袜子(hose)(莫队算法)
- bzoj 2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)&&莫队算法
- bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队算法
- 莫队总结&bzoj 2038 小Z的袜子