NKOJ P2300上司はレンガを移動するもの

NKOJ P2300上司はレンガを移動するもの

私は、セグメントツリー形式逆立ち女性を変更しないでください


KONO题面哒!

夏休みには、あなたがどのような彼の上司に行き、どのような上司は、あなただけのレンガを移動するだろうかを言うように要求されます。
  だから、上司はあなたがレンガを移動するものの強さをテストするために何を望むか:
  ボスは白いタイルのn個のブロックを持っているもの(nまでの番号1)を、彼は直線になったn個のブロックで、この番号を置くことを言いました。
  あなたはそれで逃げるためにラインに入れていると思いますか?上司は非常に奇妙な男である何、彼は彼のコマンドは、次の3つがあり、あなたの気まぐれに抑え:
  。レンガに二色c bのレンガへの最初のA。
  II。レンガ色に煉瓦のC D Bレンガための第二の色への最初の。
  III。いくつかの異なる色が存在するB番目のレンガに返信。
  
  あなたはすぐに正解ごとに質問を与える必要があり、またはあなたが仕事を得るしません!
  (7異なる色までとレンガのボスが、1-7の番号は何、白色番号1)。

データ範囲:
$ N- \ 200000のLeq、M \ $ 100000のLeq


間隔が間違った値がプッシュダウンを割り当てたため11セグメントツリーのテンはすべての周りを爆発、私は、全体の人を分割しました

一見すると、これは圧力のようなものであるということだけで7色。しかし、私は長い間プレスを作成する方法のように出てきたくなかったと思うし、暴力的なアプローチを上演しました。オープン7セグメントツリー、現在の範囲内で各色のレンガの数を記録します。
各第1号は、区間長煉瓦への電流区間に、残りの6本の木のツリーをすべての値を消去します。
各動作は、ランク2検索する\(C \) 次いで、これらのセクションを消去対象範囲記憶部レンガのツリーを(D \)\インターバル長ツリーこれらの間隔。
メモリの各ツリー対象範囲の各動作の統計上の3番には値がありません。
非常に暴力的な、少し小さな菲菲菲菲をやった後、高速に実行するために最適化されています。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#define tp(p) if((p<<1|1)<=1200010)
using namespace std;
char *p1,*p2,buf[1<<20];
#define GC (p1==p2&&(p1=buf,p2=buf+fread(buf,1,1<<20,stdin),p1==p2)?0:(*(p1++)))
//#define GC getchar()
inline int in()
{
    int x=0,w=0;
    char ch=0;
    while(!isdigit(ch)){
        w|=ch=='-';
        ch=GC;
    }
    while(isdigit(ch)){
        x=(x<<3)+(x<<1)+(ch^48);
        ch=GC;
    }
    return w?-x:x;
}
int n,m;
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
const int maxn=300010;
struct tree{
    int sum[4*maxn],tag[4*maxn];
    void pushup(int p){
        sum[p]=sum[ls(p)]+sum[rs(p)];
    }
    void pushdown(int p,int l,int r){
        int mid=((l+r)>>1);
        if(tag[p]==1){
            sum[ls(p)]=mid-l+1;
            sum[rs(p)]=r-mid;
            tag[ls(p)]=tag[rs(p)]=1;
        }
        else if(tag[p]==-1){
            sum[ls(p)]=sum[rs(p)]=0;
            tag[rs(p)]=tag[ls(p)]=-1;
        }
        tag[p]=0;
    }
    void ins(int l,int r,int p,int l1,int r1,int k)
    {
        pushdown(p,l1,r1);
        if(l<=l1&&r>=r1){
            if(k==1){
                sum[p]=r1-l1+1;
                tag[p]=1;
            }
            else{
                sum[p]=0;
                tag[p]=-1;
            }
            return;
        }
        int mid=((l1+r1)>>1);
        if(mid>=l)ins(l,r,ls(p),l1,mid,k);
        if(mid<r)ins(l,r,rs(p),mid+1,r1,k);
        pushup(p);
        return;
    }
    bool gs(int l,int r,int p,int l1,int r1)
    {
        pushdown(p,l1,r1);
        if(l<=l1&&r>=r1){
            return sum[p];
        }
        int mid=((l1+r1)>>1);
        bool res=0;
        if(mid>=l)res=(res|gs(l,r,ls(p),l1,mid));
        if(mid<r)res=(res|gs(l,r,rs(p),mid+1,r1));
        return res;
    }
}tr[8];
void change(int l,int r,int p,int l1,int r1,int c,int d)
{
    tr[c].pushdown(p,l1,r1);
    tr[d].pushdown(p,l1,r1);
    if(tr[c].sum[p]==0)return;
    
    if(l<=l1&&r>=r1&&tr[c].sum[p]==r1-l1+1){
        tr[c].sum[p]=0;
        tr[c].tag[p]=-1;
        tr[d].sum[p]=r1-l1+1;
        tr[d].tag[p]=1;
        return;
    }
    if(l1==r1)return;
    int mid=((l1+r1)>>1);
    if(mid>=l)change(l,r,ls(p),l1,mid,c,d);
    if(mid<r)change(l,r,rs(p),mid+1,r1,c,d);
    tr[c].pushup(p);
    tr[d].pushup(p);
    return;
}
int main()
{
    int i,j;
    n=in();m=in();
    tr[1].ins(1,n,1,1,n,1);
    for(i=1;i<=m;i++){
        int ch,a,b,c;
        ch=in();a=in();b=in();
        switch(ch){
            case 1:{
                c=in();
                for(j=1;j<=7;j++){
                    if(j==c)continue;
                    tr[j].ins(a,b,1,1,n,0);
                }
                tr[c].ins(a,b,1,1,n,1);
                break;
            }
            case 2:{
                int d;
                c=in();d=in();
                change(a,b,1,1,n,c,d);
                break;
            }
            case 3:{
                for(j=1;j<=7;j++)
                {
                    if(tr[j].gs(a,b,1,1,n)){
                        printf("%d ",j);
                    }
                }
                printf("\n");
                break;
            }
        }
    }
    return 0;
}

次は、神ZMR男圧力慣行のように

#include<stdio.h>
#include<bits/stdc++.h>
#define cut(l,r) ((l+r)>>1)
#define lson(i) (i<<1)
#define rson(i) ((i<<1)|1)
#define ll long long
#define intinf 1000000000
#define llinf 1000000000000000000LL
#define reint register int
#define st first
#define nd second
using namespace std;

char *p1,*p2,buf[1<<20];
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
//#define GC getchar()
inline int rd()
{
    int w=0,x=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=GC;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=GC;}
    return w?-x:x;
}
char pbuf[1<<20],*pp=pbuf;
void push(const char c){
    if(pp-pbuf==(1<<20)) fwrite(pbuf,1,(1<<20),stdout),pp=pbuf;
    *pp++=c;
}
inline void wt(int x){
    static int sta[35];int top=0;
    do{sta[top++]=x%10,x/=10;}while(x);
    while(top) push(sta[--top]+'0');
}
#define pn push('\n')
#define pk push(' ')

const int maxn=2e5+110;
const int maxr=maxn*4;
int n,m,a,b,c,d,id;
typedef pair<bool,pair<short,short> > arr;
struct node{
    int l,r;
    short sum;
    vector<arr>to_do;
}tree[maxn*4];

inline void push_up(int i)
{
    tree[i].sum=(tree[lson(i)].sum|tree[rson(i)].sum);
}

inline void push_down(int i)
{
    //标记为1表示换成颜色为change的砖
    //标记为2表示将change_from颜色的砖转换成颜色为change_to的砖
    if(!tree[i].to_do.size())return;
    arr tmp,t;
    int ls=lson(i),rs=rson(i);
    short fr,to;
    vector<arr>::iterator it;
    for(it=tree[i].to_do.begin();it!=tree[i].to_do.end();it++)
    {
        tmp=*it;fr=tmp.nd.st;to=tmp.nd.nd;
        if(tmp.st==false)
        {
            while(tree[ls].to_do.size()) tree[ls].to_do.erase(tree[ls].to_do.begin());
            while(tree[rs].to_do.size()) tree[rs].to_do.erase(tree[rs].to_do.begin());
            tree[ls].sum=(1<<(fr-1));
            tree[rs].sum=(1<<(fr-1));
            t.st=false;t.nd.st=fr;
            tree[ls].to_do.push_back(t);
            tree[rs].to_do.push_back(t);
        }
        else
        {
            t.st=true;t.nd.st=fr;t.nd.nd=to;
            if(tree[ls].sum&(1<<(fr-1)))
            {
                tree[ls].sum=(tree[ls].sum^(1<<fr-1));
                tree[ls].sum=(tree[ls].sum|(1<<(to-1)));
                tree[ls].to_do.push_back(t);
            }
            if(tree[rs].sum&(1<<(fr-1)))
            {
                tree[rs].sum=(tree[rs].sum^(1<<fr-1));
                tree[rs].sum=(tree[rs].sum|(1<<(to-1)));
                tree[rs].to_do.push_back(t);
            }
        }
    }
    while(tree[i].to_do.size()) tree[i].to_do.erase(tree[i].to_do.begin());
}

inline void build(int i,int l,int r)
{
    tree[i].l=l;tree[i].r=r;tree[i].sum=1;
    if(l==r) return;
    int mid=cut(tree[i].l,tree[i].r);
    build(lson(i),l,mid);
    build(rson(i),mid+1,r);
    push_up(i);
}

inline void change1(int i,int l,int r,int col)
{
    if(tree[i].l>=l&&tree[i].r<=r)
    {
        while(tree[i].to_do.size()) tree[i].to_do.erase(tree[i].to_do.begin());
        arr tmp;tmp.st=false;tmp.nd.st=col;
        tree[i].to_do.push_back(tmp);
        tree[i].sum=(1<<(col-1));
        return;
    }
    push_down(i);
    int mid=cut(tree[i].l,tree[i].r);
    if(mid>=l) change1(lson(i),l,r,col);
    if(mid<r) change1(rson(i),l,r,col);
    push_up(i);
}

inline void change2(int i,int l,int r,int fr,int to)
{
    if(tree[i].l>=l&&tree[i].r<=r)
    {
        arr tmp;tmp.st=true;tmp.nd.st=fr;tmp.nd.nd=to;
        if(tree[i].sum&(1<<(fr-1)))
        {
            tree[i].sum-=(1<<(fr-1));
            tree[i].sum=(tree[i].sum|(1<<(to-1)));
            tree[i].to_do.push_back(tmp);
        }
        return;
    }
    push_down(i);
    int mid=cut(tree[i].l,tree[i].r);
    if(mid>=l) change2(lson(i),l,r,fr,to);
    if(mid<r) change2(rson(i),l,r,fr,to);
    push_up(i);
}

inline int getans(int i,int l,int r)
{
    if(tree[i].l>=l&&tree[i].r<=r)
      return tree[i].sum;
    push_down(i);
    int mid=cut(tree[i].l,tree[i].r);short res=0;
    if(mid>=l) res=(res|getans(lson(i),l,r));
    if(mid<r) res=(res|getans(rson(i),l,r));
    return res;
}

int main()
{
    n=rd();m=rd();
    build(1,1,n);
    for(reint i=1;i<=m;i++)
    {
        id=rd();
        if(id==1)
        {
            a=rd();b=rd();c=rd();
            change1(1,a,b,c);
        }
        else if(id==2)
        {
            a=rd();b=rd();c=rd();d=rd();
            change2(1,a,b,c,d);
        }
        else
        {
            a=rd();b=rd();
            int ans=getans(1,a,b);
            for(short j=1;j<=7;j++)
              if(ans&(1<<(j-1))) push(j+'0'),pk;
            pn;
        }
    }
    fwrite(pbuf,1,pp-pbuf,stdout);
    return 0;
}

C96変換WSL!

おすすめ

転載: www.cnblogs.com/cooper233/p/11983491.html