CodeForces 444C DZY Loves Colors題解

[題意]

     有n個氣球,每個氣球有一個顏色x,改變爲y後,美麗值增加|x-y|.

     對一個序列有兩種操作:

1.    把區間在[L,R]的顏色染成x.

2.   詢問區間[L,R]的氣球的美麗值總和.

n<=1e5,1<=x<=1e8.

[思路]

     區間更新,區間詢問可以聯想到線段樹.

     只是更新的時候有點複雜:

     因爲一個區間內的顏色不一定相同,無法一次性全部更新,那麼我們就直接更新顏色相同的一塊,把這一個區間都改變.再延遲更新,詢問和更新的時候down下去.

     一直一直Wa的原因:

     在延遲更新的時候直接記錄的是更新後的顏色,但是,這樣是不行滴:一開始顏色是1,改爲4,再改爲2,答案是5,但是如果直接改成了2,答案就是1了.

當更新的區間越長,更新的時候就會進行地越深,訪問的區間更多;

但更新後的區間的顏色是相同的,那麼就會越有利於下次更新.兩者的制約關係是不會超時的一個因素.

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#define ll long long
using namespace std;
inline void rd(int &res){
    res=0;char c;
    while(c=getchar(),c<48);
    do{
        res=(res<<1)+(res<<3)+(c^48);
    }while(c=getchar(),c>=48);
}
inline void print(ll k){
    if(k==0)return ;
    print(k/10);
    putchar((k%10)^48);
}
inline void sc(ll k){
    print(k);
    if(k==0)putchar('0');
    putchar('\n');
}
const int M=1e5+5;
int  n,m;
struct node{
    ll b,c;//b爲美麗值的和,c是顏色差的疊加(用於延遲更新).
    int f;//f表示當前的顏色
}T[M*4];
void UP(int p){
    T[p].b=T[p<<1].b+T[p<<1|1].b;
    if(T[p<<1].f==T[p<<1|1].f&&T[p<<1].f)T[p].f=T[p<<1].f;
    else T[p].f=0;
}
void down(int l,int r,int p){
    if(T[p].c==0)return ;
    int mid=(l+r)>>1;
    ll x=T[p].c;
    T[p<<1].b+=1ll*(mid-l+1)*x;//[l,mid];
    T[p<<1|1].b+=1ll*(r-mid)*x;//[mid+1,r]
    T[p<<1|1].f=T[p<<1].f=T[p].f;
    T[p<<1].c+=x;T[p<<1|1].c+=x;
    T[p].c=0;
}
void build(int l,int r,int p){
    T[p].f=0;T[p].c=0;T[p].b=0;
    if(l==r){T[p].f=l;return ;}
    int mid=(l+r)>>1;
    build(l,mid,p<<1);
    build(mid+1,r,p<<1|1);
}
void update(int L,int R,int l,int r,int x,int p){
    if(L==l&&R==r&&T[p].f){//[l,r]內的顏色更新爲x 
        T[p].b+=1ll*(r-l+1)*abs(T[p].f-x);//
        T[p].c+=abs(T[p].f-x);//答案要疊加
T[p].f=x;
        return ;
    }
    down(L,R,p);
    int mid=(L+R)>>1;
    if(r<=mid)update(L,mid,l,r,x,p<<1);
    else if(l>mid)update(mid+1,R,l,r,x,p<<1|1);
    else {update(L,mid,l,mid,x,p<<1);update(mid+1,R,mid+1,r,x,p<<1|1);}
    UP(p)//更新完再Up回來
}
ll query(int L,int R,int l,int r,int p){
    down(L,R,p);
    if(L==l&&R==r)return T[p].b;
    int mid=(L+R)>>1;
    if(r<=mid)return query(L,mid,l,r,p<<1);
    else if(l>mid)return query(mid+1,R,l,r,p<<1|1);
    else return query(L,mid,l,mid,p<<1)+query(mid+1,R,mid+1,r,p<<1|1);
}
int main(){
    int i,j,k,a,b,c,d;
    scanf("%d %d",&n,&m);
    build(1,n,1);
    for(i=1;i<=m;i++){
        rd(a);rd(b);rd(c);
        if(a==1){
            rd(d);
            update(1,n,b,c,d,1);
        }
        else sc(query(1,n,b,c,1));  
    }
    return 0;
}</span>
20160627離線賽/CodeForces 444C

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章