查看: 1480|回復: 1
打印 上一主題 下一主題

[CF] [線段樹][LayzFlag]444C - DZY Loves Colors

[複製鏈接]
  • TA的每日心情
    慵懶
    2015-4-10 14:18
  • 簽到天數: 78 天

    [LV.6]常住居民II

    176

    主題

    612

    帖子

    3959

    積分

    管理員

    Rank: 9Rank: 9Rank: 9

    積分
    3959

    台南一中資訊社新手達陣程式設計達人 - 2014

    跳轉到指定樓層
    樓主
    發表於 2015-2-6 21:37:55 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

    趕快加入我們來參與討論吧!

    您需要 登錄 才可以下載或查看,沒有帳號?加入我們

    x
    原題:http://codeforces.com/problemset/problem/444/C

    做線段樹時,維護Flag : color,如果 [tex]color = -1[/tex]代表該區間所涵蓋的所有點為同一顏色,還算簡單,稍微維護一下標記就行了,各個操作就能以對數時間完成。
    要開long long XD
    [C++] 純文本查看 復制代碼
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    struct node{
    	long long sum;
    	long long size;
    	long long color;
    	long long etd;
    	long long s()const{
    		return sum+size*etd; 
    	}
    };
    node d[400000] = {0,0,0,0};
    int N,M;
    #define LI(X) ((X)*2+1)
    #define RI(X) ((X)*2+2)
    #define rmq 1,N,0
    void down(int I)
    {
    	if(d[I].color==-1)return ;
    	if(d[I].size == 1){
    		d[I].sum+=d[I].etd;
    		d[I].etd = 0;
    	}
    	d[I].sum = d[I].s();
    	d[LI(I)].etd+=d[I].etd;
    	d[RI(I)].etd+=d[I].etd;
    	d[I].etd = 0;
    	d[LI(I)].color = d[I].color;
    	d[RI(I)].color = d[I].color;
    }
    node merge(node a,node b)
    {
    	node c;
    	c.size = a.size + b.size ;
    	c.sum  = a.s()  + b.s();
    	c.etd  = 0;
    	c.color= (a.color==b.color)?a.color:-1;
    	return c;
    }
    void update(int l,int r,int c,bool init,int L,int R,int I)
    {
    	
    	if(l==L&&R==r&&d[I].color!=-1||l==L&&R==r&&l==r)
    	{
    		int add = abs( d[I].color - c );
    		if(init){
    			d[I].sum=d[I].etd=0;
    		}
    		else{
    			d[I].etd+=add;
    		}
    		d[I].color=c;
    		d[I].size =R-L+1;
    		return ;
    	}
    	down(I);
    	int M=(L+R)/2;
    	if( r<=M ) 		update(l,r,c,init,L  ,M,LI(I));
    	else if( M< l ) update(l,r,c,init,M+1,R,RI(I));
    	else { 	update(l  ,M,c,init,L  ,M,LI(I)); 
    			update(M+1,r,c,init,M+1,R,RI(I)); 
    	}
    	d[I] = merge(d[LI(I)],d[RI(I)]);
    }
    
    node query(int l,int r,int L,int R,int I)
    {
    	if(l==L&&r==R)return d[I];
    	down(I);
    	int M=(L+R)/2;
    	if( r<=M )return query(l,r,L  ,M,LI(I));
    	if( M< l )return query(l,r,M+1,R,RI(I));
    	return merge(	query(l  ,M,L  ,M,LI(I)) ,  
    					query(M+1,r,M+1,R,RI(I)) );
    }
    
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cin>>N>>M;
    	int a,b,c,d;
    	for(int i=1;i<=N;++i)
    		update(i,i,i,true,rmq);
    	while(M--)
    	{
    		cin>>a;
    		if(a==1)
    		{
    			cin>>b>>c>>d;
    			update(b,c,d,false,rmq);
    		}
    		else //a==2
    		{
    			cin>>b>>c;
    			node tmp = query(b,c,rmq);
    			cout<<tmp.s()<<'\n';
    		}
    	}
    }

    點評

    這題的難點感覺是在證明它的複雜度  發表於 2015-2-8 10:05
    回復

    使用道具 檢舉

    您需要登錄後才可以回帖 登入 | 加入我們

    本版積分規則

    快速回覆 返回頂部 返回列表