트리 라인의 [UOJ 번호 (218)] [UNR # 1 기차 지속 가능 경영

면책 조항 :이 문서는 블로거 원본입니다, 추적 에 의해-SA의 CC 4.0 저작권 계약, 복제, 원본 소스 링크이 문을 첨부 해주세요.
이 링크 : https://blog.csdn.net/ALPS233/article/details/51956364

주제 :
기차가 UOJ에 속하는 관리하는 데 사용 기차 정류장, 거기 UOJ.

N- 형의 총 훈련
N- 형
조각 1, ..., N- 형 번호가
1, ..., N- 형
단지로 인해 특별한 구조에 기차 레일의 한쪽 끝, 기차를 보유하는 데 사용, 각 철도 차량이 주차 할 수있는 수많은 작은 기차를. 각 철도는 서로 독립적입니다.

주차 된 기차가 먼저 나올 수 후 철도, 스택 구조입니다.

기차 당 톤수는 t의가
t을
.

NOI2016오고 있기 때문에, 당신은 하루에 많은 이벤트를 처리 할 수있는 작은 앞 사람을 싸우고, 기차역 관리자 아홉 개 가난한 필요로 훈련을합니다.

같은 사건의 약 3 종류의 요약 될 수있다 :
• 1 LR 누군가에 철도 번호에 원하는 [L, R]
[L, R]
작은 각 철도가 처음 기차 싸움에서 캔을 열어 긍정적, 당신은 이러한 통계를 훈련 할 필요가 톤수없이 철도 열차는 대답에 포함되지 않습니다.
• 2리터 번호 L의
L의
철도는 더 기차 밖으로하지 않는 경우 철도 기차를 몰았다.
[L, R]에서 • 3 LRX 철도 번호
[L, R]
각 철도는 X-의 새로운 공원 톤수있는
X 축에
기차.

이제 그를 위해 당신이 기차역을 관리하는 데 필요한, 남중국해의 최전선에 가서 아홉 가난한 관리자.

바쁜 기차역으로, 그래서 당신은 실시간 피드백이 필요합니다, 우리는 온라인으로 강제로 특정 입력 형식을 보려면 몇 가지 방법을 사용하도록 요구합니다.

입력 형식

첫 번째 행의 세 음이 아닌 정수 N-, m의 입력은 TY
N-, m은 TY는
동작 횟수 및 철도 및 필수 여부 개수를 나타낸다.

이어서 m에서
m의
세 개의 숫자 또는 네 개의 숫자 또는 숫자의 행은 하나의 동작을 나타낸다.

실시간 피드백 정보는 L, R & LT 해독 할 필요가
L, R & LT를
제공하는 판독 L1, R1
L1, R1
, 실제 값은 다음과 같다 :

==== L2r2lr (L1 + Lastans⋅ty) Modn + 1 (R1 + Lastans⋅ty) Modn + 볼 (L2, R2) 1 분 에서 최대 (L2, R2)
L2 = (L1 + Lastans⋅ty) Modn + 1R2 = ( R1 +의 lastans⋅ty) modn 1리터 + = 분 (L2, R2) R = 최대 (L2, R2)

lastans는
lastans
질의에 대한 답 한 번하지 않을 경우 요청하기 전에 또는 0, 표현
0
.

는 동작의 제 2 타입 있으므로 만 L = (L1 + lastans⋅ty) modN. 1 + 수행 할 때
L = (L1 + lastans⋅ty) modN +. (1)
에있다.

입력 데이터는 1≤l1, r1≤n 보장하기 위해
, r1≤n을 1≤l1을
.

우리는 톤수 및 운영의 유형을 암호화하지 않아도됩니다

출력 형식

질문의 각 출력 라인, 음이 아닌 정수의 답.

샘플

입력
10 10 0
3 1 5 3
1 1 6
3 1 7 1
1 1 9
1 1 6
3 5 2 1
1 3 6
1 3 9
3 1 7 6
2 1

출력
15
7
6
7
8

http://uoj.ac/problem/218
솔루션 :

우리는 시간에 나무의 지속 가능한 세그먼트를 구축 스택 열차의 각 레일 톤수 및 상단의 각 기간에 대한 스택의 스택 상단을 유지할 수 있습니다.
우리가 통계 대답 세그먼트 트리를 유지합시다.
그래서 단지 세에서 작동하는 다음
의 질문의 범위 : 직접 질문 세그먼트 트리에 대답 할 수 있습니다.
간격 압력 : 트리 라인 커버에 대한 섹션에서 지속적으로, 그리고 다음 응답 세그먼트 트리에서 변경.
단일 지점 폭탄의 수 : 우리는 스택 시간을 기록하기 때문에, 시간 t에 대한 인바운드 문의, 우리는 다음 트리 라인과 대답을, 시간 t 전에 나무를 조회 현재 시점 스택 전에 스택의 상단에 정보를 찾을 수 있습니다 지속성 트리 라인을 수정할 수 있습니다.

코드 :

#include<iostream>
#include<stdio.h>
#include<string.h>
#define N 500005
#define lson id*2
#define rson id*2+1
using namespace std;
int n,m,sum[N*4],lazy[N*4];

void pd(int id,int l,int r,int mid)
{
    if(lazy[id]==-1) return ;
    sum[lson]=(mid-l+1)*lazy[id];
    sum[rson]=(r-mid)*lazy[id];
    lazy[lson]=lazy[rson]=lazy[id];
    lazy[id]=-1;
}
void add(int id,int L,int R,int l,int r,int v)
{
    //cout<<L<<"  "<<R<<"  "<<l<<" "<<r<<endl;
    if(L>r||R<l) return ;
    if(L>=l&&R<=r)
    {
        lazy[id]=v;
        sum[id]=(R-L+1)*v;
        return ;
    }
    int mid=(L+R)>>1;
    pd(id,L,R,mid);
    add(lson,L,mid,l,r,v);
    add(rson,mid+1,R,l,r,v);
    sum[id]=sum[lson]+sum[rson];
}
int getans(int id,int L,int R,int l,int r)
{
    if(L>r||R<l) return 0;
    if(L>=l&&R<=r) return sum[id];
    int mid=(L+R)>>1;
    pd(id,L,R,mid);
    int ret=getans(lson,L,mid,l,r)+getans(rson,mid+1,R,l,r);
    return ret;
}

int tim[N*75],val[N*75],tot,ls[N*75],rs[N*75];
int rt[N];

void down(int id)
{
    if(tim[id]==-1) return;
    ++tot;tim[tot]=tim[id];ls[tot]=ls[ls[id]];rs[tot]=rs[ls[id]];ls[id]=tot;val[tot]=val[id];
    ++tot;tim[tot]=tim[id];ls[tot]=ls[rs[id]];rs[tot]=rs[rs[id]];rs[id]=tot;val[tot]=val[id];
    tim[id]=-1;
}
void build(int pre,int &now,int L,int R,int l,int r,int t,int v)
{
    now=++tot;

    if(L>=l&&R<=r)
    {
        tim[now]=t;
        val[now]=v;
        return ;
    }   //cout<<L<<"   "<<R<<"           "<<l<<" "<<r<<endl;
    if(pre) down(pre);
    ls[now]=ls[pre],rs[now]=rs[pre];
    int mid=(L+R)>>1;
    if(mid>=l) build(ls[pre],ls[now],L,mid,l,r,t,v);
    if(mid+1<=r) build(rs[pre],rs[now],mid+1,R,l,r,t,v);
}
int get(int id,int l,int r,int pos)
{
    if(!id||tim[id]!=-1) return id;
    int mid=(l+r)>>1;
    if(pos<=mid) return get(ls[id],l,mid,pos);
    return get(rs[id],mid+1,r,pos); 

}
void del(int x,int y)
{
    int id=get(rt[y-1],1,n,x);
    if(!id)
    {
        rt[y]=rt[y-1];
        return ;
    }   
//  if(tim[id]==0) while(1);
    id=get(rt[tim[id]-1],1,n,x);
    build(rt[y-1],rt[y],1,n,x,x,tim[id],val[id]);
    add(1,1,n,x,x,val[id]);
}
void change(int l,int r,int v,int i)
{
    build(rt[i-1],rt[i],1,n,l,r,i,v);

    add(1,1,n,l,r,v);
} 
int ty;
int ans;
int main()
{
    scanf("%d%d%d",&n,&m,&ty);
    memset(lazy,-1,sizeof(lazy));
    memset(tim,-1,sizeof(tim));
    for(int i=1,aa,bb,cc,dd;i<=m;i++)
    {

        scanf("%d",&aa);

        if(aa==1)
        {
            scanf("%d%d",&bb,&cc);
            bb=(bb+ans*ty)%n+1;
            cc=(cc+ans*ty)%n+1;
            if(bb>cc) swap(bb,cc);
            ans=getans(1,1,n,bb,cc);
            printf("%d\n",ans); 
            rt[i]=rt[i-1];
        }
        else if(aa==2)
        {
            scanf("%d",&bb);
            bb=(bb+ans*ty)%n+1;
            del(bb,i);
        }
        else if(aa==3)
        {
            scanf("%d%d%d",&bb,&cc,&dd);
            bb=(bb+ans*ty)%n+1;
            cc=(cc+ans*ty)%n+1;
            if(bb>cc) swap(bb,cc);
            change(bb,cc,dd,i);
        }
    }

} 

추천

출처blog.csdn.net/ALPS233/article/details/51956364