luogu P2709 小B的詢問 最簡單的莫隊
阿新 • • 發佈:2019-04-12
簡練 har 後來 std getch -- namespace getchar() inline
塊內按右端點sort,塊外按左端點sort
話說我剛開始這麽修改。。。
inline void del(int i) {cnt-=(c[a[i]]*c[a[i]]),cnt+=(c[a[i]]-1)*(c[a[i]]-1),--c[a[i]];} inline void ins(int i) {cnt-=(c[a[i]]*c[a[i]]),cnt+=(c[a[i]]+1)*(c[a[i]]+1),++c[a[i]];}
十分暴力?沒事不影響復雜度。。
後來看題解發現可以改成這樣
inline void del(int i) {--c[a[i]],cnt-=2*c[a[i]]+1;} inline void ins(int i) {++c[a[i]],cnt+=2*c[a[i]]-1;}
十分簡練?我數學太菜了。。。
#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #define R register int using namespace std; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==‘-‘?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } int n,m,k,T,l=1,r=0; long long cnt=0,ans[50010]; int c[50010],a[50010]; struct seg { int l,r,rk; bool operator <(const seg& y)const{return (l-1)/T==(y.l-1)/T?r<y.r:l<y.l;} }q[50010]; inline void del(inti) {--c[a[i]],cnt-=2*c[a[i]]+1;} inline void ins(int i) {++c[a[i]],cnt+=2*c[a[i]]-1;} signed main() { n=g(),m=g(),k=g(); T=1.2*sqrt(n); for(R i=1;i<=n;++i) a[i]=g(); for(R i=1;i<=m;++i) q[i].l=g(),q[i].r=g(),q[i].rk=i; sort(q+1,q+m+1); for(R i=1;i<=m;++i) { while(l<q[i].l) del(l++); while(l>q[i].l) ins(--l); while(r<q[i].r) ins(++r); while(r>q[i].r) del(r--); ans[q[i].rk]=cnt; } for(R i=1;i<=m;++i) printf("%lld\n",ans[i]); }
2019.04.12
luogu P2709 小B的詢問 最簡單的莫隊