[モリブデン] +ビットセットチーム羅区P4688

タイトルしっくいプライム晴れた日 実際には、自宅で両親が蘇晴れた日再生できないため、

私たちはしばしば、カードを望んでいないのメモリに問題に対する解決策を書き最も劣ったソリューションを使い果たした......

だけにして、その後どのように行う、同じ色の範囲のようなものを求めて検討している場合もちろん、それは、第1の離散外観です

開くことができる(\ texttt {ビット集合} \ \ ) の各色は、その後、三つのセクション発生しない記録\(\ texttt {ビット集合} \ ) を合わせたが、複合答えは\(\ texttt {ビット集合} \ )\(1 \)

処理セクションの各\(\ texttt {ビットセットは} \ ) のMoをチームができ

マージは、私はおそらく、すべて、解答スペースはそれほどグループ求めて検討し、揚げされた\(5000 \) 1グループの実行に尋ねます

元のタイトルに良好な表面バックは、同じ3つの区間は、色番号の数を求める必要。しない限り、別個の重量として、有する(NXT [X] \)\記録(X \)\次に(\ \ texttt {ビット集合} \ ) のライン上の位置に、またはその実践上。

#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x);i<=(y);++i)
#define FoR(i,x,y,z) for(int i=(x);i<=(y);i+=(z))
#define Rof(i,x,y) for(int i=(x);i>=(y);--i)
#define RoF(i,x,y,z) for(int i=(x);i>=(y);i-=(z))
#define Edge(x) for(int i=head[x],to=e[i].v;i;i=e[i].nxt,to=e[i].v)
typedef long long ll;
const int N=100005;
const int M=5000;
using namespace std;

template<typename T> void rd(T& x){
    T y=0;int f=1;char c=getchar();
    while(c<'0' || c>'9')
    { c=getchar(); if(c=='-')f=-f; }
    while(c>='0' && c<='9') y=y*10+c-'0',c=getchar();
    x=y*f;
}

int a[N],b[N],bl[N],cnt,nxt[N],tim[N],ans[N],L[N][3],R[N][3],n;
bitset<N> tmp,p[M+2];
struct qwq{
    int l,r,id;
    bool operator <(const qwq &x)const
    { return bl[l]==bl[x.l]?(bl[l]&1?r<x.r:r>x.r):bl[l]<bl[x.l]; }
}q[3*M+5];

void add(int t,int x)
{ x=a[x]; if(tim[x]<t) tim[x]=t,nxt[x]=x; tmp[nxt[x]++]=1; }
void del(int x)
{ x=a[x],tmp[--nxt[x]]=0; }
void solve(int t){
    int l=1,r=0; tmp.reset();
    sort(q+1,q+cnt+1);
    For(i,1,cnt){
        while(l>q[i].l) add(t,--l);
        while(r<q[i].r) add(t,++r);
        while(l<q[i].l) del(l++);
        while(r>q[i].r) del(r--);
        p[q[i].id]&=tmp;
    }
    For(i,0,M-1){
        if(t*M+i>n) return;
        ans[t*M+i]-=3*p[i].count();
    }
}

int main(){
//  freopen("in.txt","r",stdin);
//  freopen("wa.txt","w",stdout);
    int m; rd(n),rd(m);
    int block=sqrt(n);
    For(i,1,n) rd(a[i]),b[i]=a[i]; sort(b+1,b+n+1);
    For(i,1,n) a[i]=lower_bound(b+1,b+n+1,a[i])-b;
    For(i,1,n) bl[i]=(i-1)/block+1;
    
    For(i,0,m-1) For(j,0,2){
        rd(L[i][j]),rd(R[i][j]);
        ans[i]+=R[i][j]-L[i][j]+1;
    }
    memset(tim,-1,sizeof(tim));
    For(i,0,(m+M-1)/M){
        cnt=0;
        For(j,i*M,min(m-1,i*M+M-1)){
            p[j%M].set();
            For(k,0,2) q[++cnt]=(qwq){L[j][k],R[j][k],j%M};         
        }
        solve(i);
    }
    For(i,0,m-1) printf("%d\n",ans[i]);
}

おすすめ

転載: www.cnblogs.com/PsychicBoom/p/12234544.html