天天看點

HH的項鍊

​​P1972 [SDOI2009]HH的項鍊​​

莫隊模闆題,但是有點點卡常,需要用一些技巧進行優化

(1)奇偶優化

(2)快讀快寫

(3)把塊的大小開大一點取\(n^{0.5+}\)效果會好一些

(4)把 add 和 del 函數展開,不以函數的形式,會塊一點點,但并不會快太多

// Created by CAD
#include <bits/stdc++.h>

using namespace std;

const int maxn=1e6+5;
int a[maxn],belo[maxn];
struct query{
    int l,r,id;
    bool operator <(const query& q)const {
        return belo[l]==belo[q.l]?(belo[l]&1?r<q.r:r>q.r):belo[l]<belo[q.l];
    }
}q[maxn];
int ans[maxn],cnt[maxn],now;

struct FastIO {
    static const int S = 4e6;
    int wpos;
    char wbuf[S];
    FastIO() : wpos(0) {}
    inline int xchar() {
        static char buf[S];
        static int len = 0, pos = 0;
        if (pos == len)
            pos = 0, len = fread(buf, 1, S, stdin);
        if (pos == len) exit(0);
        return buf[pos++];
    }
    inline int xuint() {
        int c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x;
    }
    inline void wchar(int x)
    {
        if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
        wbuf[wpos++] = x;
    }
    inline void wint(int x)
    {
        if (x < 0) wchar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n++] = '0' + x % 10, x /= 10;
        while (n--) wchar(s[n]);
        wchar('\n');
    }
    ~FastIO()
    {
        if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
    }
} io;

inline void add(int x){
    now+=(cnt[a[x]]++==0);
}
inline void del(int x){
    now-=(--cnt[a[x]]==0);
}
int main() {
    int n,m;
    n=io.xuint();
    int blo=pow(n,0.56);
    for(int i=1;i<=n;++i){
        a[i]=io.xuint();
        belo[i]=(i-1)/blo+1;
    }
    m=io.xuint();
    for(int i=1;i<=m;++i){
        q[i].l=io.xuint(),q[i].r=io.xuint();
        q[i].id=i;
    }
    sort(q+1,q+1+m);
    int l=1,r=0;
    int ql,qr;
    for(int i=1;i<=m;++i){
        ql=q[i].l,qr=q[i].r;
        while(l<ql) del(l++);
        while(l>ql) add(--l);
        while(r<qr) add(++r);
        while(r>qr) del(r--);
        ans[q[i].id]=now;
    }
    for(int i=1;i<=m;++i)
        io.wint(ans[i]);
    return 0;
}      

繼續閱讀