Educational Codeforces Round 36 (Rated for Div. 2) E(動態開點線段樹)

題目鏈接

題意:輸入n 、q  n<1e9 代表n天   和  q次操作 輸入l,r,k  

1、k==1 區間內 l,r變成不工作日

2、k==2 區間內l,r, 變成工作日

3、剛開始n天都是工作日

4、問每次操作後 工作日的數量

做法動態開點線段樹+區間lazy維護即可

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=3e5+10;
int sum[50*N],ls[50*N],rs[50*N],lazy[50*N],cnt;
void pushdown(int id,int l,int r)
{
    if(lazy[id]!=-1){
        //printf("paush:%d\n",id);

        int mid=l+r>>1;
        if(ls[id]==0)ls[id]=++cnt;
        lazy[ls[id]]=lazy[id];
        sum[ls[id]]=(mid-l+1)*lazy[id];

        if(rs[id]==0) rs[id]=++cnt;
        lazy[rs[id]]=lazy[id];
        sum[rs[id]]=(r-mid)*lazy[id];

        lazy[id]=-1;
    }
}
void up(int &id,int l,int r,int ql,int qr,int val)
{
    if(id==0) id=++cnt;
    if(ql<=l&&r<=qr){
        //printf("id:%d\n",id);
        sum[id]=(r-l+1)*val;
        lazy[id]=val;
        return ;
    }
    pushdown(id,l,r);
    int mid=l+r>>1;
    if(ql<=mid) up(ls[id],l,mid,ql,qr,val);
    if(qr>mid) up(rs[id],mid+1,r,ql,qr,val);
    sum[id]=sum[ls[id]]+sum[rs[id]];
}
void solve()
{
    int n;scanf("%d",&n);
    memset(lazy,-1,sizeof(lazy));
    int root=++cnt;
    sum[root]=n,lazy[root]=1;
    int _;cin>>_;while(_--)
    {
        int l,r,k;
        scanf("%d%d%d",&l,&r,&k);
        if(k==1){
            up(root,1,n,l,r,0);
        }
        else{
            up(root,1,n,l,r,1);
        }
        printf("%d\n",sum[root]);
    }

}
int main()
{

	//int _;cin>>_;while(_--)
	solve();
}

 

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