BZOJ 2120:修理チームのMoと色数(Moは永続的なチームすることができます)

クリエイティブコモンズライセンス 著作権:帰属、紙ベースを作成するために他人を許可し、(同じライセンスで元のライセンス契約に基づいて用紙配布する必要がありますクリエイティブコモンズ

タイトル

BZOJ 2120
LUOGU 1903
説明

インクインクが列に配置され、(同じ色であってもよい、その一部)N分岐色のブラシを買って、あなたが質問にインクインクに答える必要があります。インクインクは、以下の手順を公開し、あなたを好きになるでしょう:1、QLRは最初のRブラシにLからブラシの合計に代わってブラシのいくつかの異なる色をお願いします。2、RPコルブラシはP大佐の色を置き換えます インクでインクの要件を満たすために、あなたはそれを行う必要があります知っていますか?

入力

1行目二つの整数N、M、インクのペンのインクの初期数の数を表すと物事を行います。最初のi行分枝筆ペンの色を表す行2 Nの整数、。2 + M行第3列は、インクのインクを表す各行はカジュアル作業部としてフォーマットことを行います。

出力

各クエリのクエリに対して、あなたが対応する行の数を与える必要があり、LはRブラシいくつかの異なる色をブラシの合計ブラシを表します。

サンプル入力

6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1つの2
Q 1 4
Q 2 6

サンプル出力

4
4
3
4

ヒント

データの100%に、N≤10000、M≤10000は、操作を1000以上を変更し、すべての入力データが出現するすべての整数は^ 6 10以上1未満ではないではありません。
2016年3月2日Nano_Apeすることにより、新しいデータセットを追加

分析

まず資料:「ネットワーク全体で最も詳細な、Moのアルゴリズムチームには4つのカテゴリのほとんどが説明します」

私たちは、それはあまりにも無味ではありません、Moの普通のチームは、一般的に変更することができない見つけ、ひいては、兄のMo修理チームを思い付く、または8つのワードと思っていますお問い合わせは、ポインタの跳ね返りを命じましたただ、1つの以上のポインタ T T 、期間ポインタのみ。

だから我々は、ソートのになった:3回目の最初のキー、ノードへの第二の鍵のサイズの右端の左端にブロックキーワードポイントの数を問い合わせるソート。そして、そのような情報の各バージョンの歴史に関する記録として会長ツリー高度なデータ構造としてすることができます。

それを見るために具体的な言及。

コード

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e4+10,maxcol=1e6+1;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

template<typename T>inline void write(T x)
{
    if (!x) { putchar('0'); return ; }
    if (x<0) putchar('-'), x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) putchar(ch[num--]);
}

struct Orz{int l,r,t,id,ans;}q[maxn];
int belong[maxn];
inline bool cmp1(Orz a,Orz b)
{
    return belong[a.l]^belong[b.l]?a.l<b.l:(belong[a.r]^belong[b.r]?a.r<b.r:a.t<b.t);
}

inline bool cmp2(Orz a,Orz b)
{
    return a.id<b.id;
}

int color[maxcol],ans;
inline void revise(int col,int opt)
{
    color[col]+=opt;
    if (opt>0) ans+=(color[col]==1)?1:0;
    else    ans-=(color[col]==0)?1:0;
}

int a[maxn],now[maxn],l=1,r=0,t=0,Tim,T;
inline void doit(int pos,int col)
{
    if (l<=pos && pos<=r) revise(col,1),revise(a[pos],-1);
    a[pos]=col;
}

struct QWQ{int pos,Old,New;}c[maxn];
int main()
{
    int n,m;
    read(n);read(m);
    int block=floor(pow(n,2.0/3));
    for (int i=1; i<=n; ++i) read(a[i]),now[i]=a[i],belong[i]=(i-1)/block+1;
    for (int i=1,x,y; i<=m; ++i)
    {
        char ch=getchar();
        read(x);read(y);
        if (ch=='Q') q[++T]=(Orz){x,y,Tim,T};
        else c[++Tim]=(QWQ){x,now[x],y},now[x]=y;
    }

    sort(q+1,q+T+1,cmp1);
    for (int i=1; i<=T; ++i)
    {
        while (t<q[i].t) ++t,doit(c[t].pos,c[t].New);
        while (t>q[i].t) doit(c[t].pos,c[t].Old),--t;
        
        while (l<q[i].l) revise(a[l++],-1);
        while (l>q[i].l) revise(a[--l],1);
        while (r<q[i].r) revise(a[++r],1);
        while (r>q[i].r) revise(a[r--],-1);
        q[i].ans=ans;
    }
    sort(q+1,q+T+1,cmp2);
    for (int i=1; i<=T; ++i) write(q[i].ans),puts("");
    return 0;
}

おすすめ

転載: blog.csdn.net/huashuimu2003/article/details/92066306