一、不带修莫队

模板（洛谷P2709 小B的询问

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long
using namespace std;
int x(0),w(1); char c = getchar();
while(c^'-' && (c<'0'||c>'9')) c = getchar();
if(c == '-') w = -1, c = getchar();
while(c>='0' && c<='9') x = (x<<3) + (x<<1) + c - '0', c = getchar();
return x*w;
}
struct Query{
int l,r,idx;
ll ans;
}q[50010];
int n,m,K,L,R,sz;
ll ans;
int a[50010],cnt[50010];
inline bool cmp(const Query& A, const Query& B){
if(A.l/sz != B.l/sz) return A.l/sz < B.l/sz;
return A.r < B.r;
}
inline bool cmp2(const Query& A, const Query& B){
return A.idx < B.idx;
}
inline void inc(int P){
ans += (ll)2*(ll)cnt[a[P]]+(ll)1;
++cnt[a[P]];
}
inline void dec(int P){
ans -= (ll)2*(ll)cnt[a[P]]-(ll)1;
--cnt[a[P]];
}
int main(){
sz = 223;
for(int i = 1; i <= n; ++i) a[i] = read();
for(int i = 1; i <= m; ++i){
q[i].idx = i;
}
sort(q+1,q+m+1,cmp);
L = R = 1;
inc(1);
for(int i = 1; i <= m; ++i){
while(R < q[i].r) inc(++R);
while(R > q[i].r) dec(R--);
while(L < q[i].l) dec(L++);
while(L > q[i].l) inc(--L);
q[i].ans = ans;
}
sort(q+1,q+m+1,cmp2);
for(int i = 1; i <= m; ++i){
printf("%lld\n",q[i].ans);
}
return 0;
}

二、带修莫队

$\dfrac{y}{n}=\dfrac{n^2}{B^2}+B+\dfrac{n}{B}$

$t^2+\dfrac{n}{t}=t^2+\dfrac{n}{2t}+\dfrac{n}{2t} \geq 3\sqrt[3]{t^2*\dfrac{n}{2t}*\dfrac{n}{2t}}=3\sqrt[3]{\dfrac{n^2}{4}}$

/*DennyQi 2019*/
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int x(0),w(1); char c = getchar();
while(c^'-' && (c<'0'||c>'9')) c = getchar();
if(c == '-') w = -1, c = getchar();
while(c>='0' && c<='9') x = (x<<3) + (x<<1) + c - '0', c = getchar();
return x*w;
}
struct Query{ int l,r,t,idx,ans; }q[50010];
int n,m,T,x,y,Q,ans,L,R,cur_T,sz;
int a[50010],b[50010],md[50010],mdc[50010],cnt[1000010];
char s[10];
inline bool cmp(const Query& A, const Query& B){
if(A.l/sz != B.l/sz) return A.l < B.l;
if(A.r/sz != B.r/sz) return A.r < B.r;
return A.t < B.t;
}
inline bool cmp2(const Query& A, const Query& B){ return A.idx < B.idx; }
inline void inc(int P){ if(cnt[a[P]]++ == 0) ++ans; }
inline void dec(int P){ if(--cnt[a[P]] == 0) --ans; }
inline void modify(int i, int _L, int _R){
int P = md[i];
if(_L <= P && P <= _R){
if(--cnt[a[P]] == 0) --ans;
swap(a[P],mdc[i]);
if(cnt[a[P]]++ == 0) ++ans;
}
else swap(a[P],mdc[i]);
}
int main(){
scanf("%d%d",&n,&m);
sz = 1357;
for(int i = 1; i <= n; ++i) scanf("%d",a+i);
for(int i = 1; i <= m; ++i){
scanf("%s",s);
if(s[0] == 'Q'){
++Q;
scanf("%d%d",&q[Q].l,&q[Q].r);
q[Q].idx = Q, q[Q].t = T;
}
else{
++T;
scanf("%d%d",&md[T],&mdc[T]);
}
}
sort(q+1,q+Q+1,cmp);
inc(L=R=1);
for(int i = 1; i <= Q; ++i){
while(L < q[i].l) dec(L++);
while(L > q[i].l) inc(--L);
while(R < q[i].r) inc(++R);
while(R > q[i].r) dec(R--);
while(cur_T < q[i].t) modify(++cur_T,q[i].l,q[i].r);
while(cur_T > q[i].t) modify(cur_T--,q[i].l,q[i].r);
q[i].ans = ans;
}
sort(q+1,q+Q+1,cmp2);
for(int i = 1; i <= Q; ++i){
printf("%d\n",q[i].ans);
}
return 0;
}

三、树上莫队

posted @ 2019-05-22 10:55  DennyQi  阅读(209)  评论(0编辑  收藏  举报