线段树双tag+差分数组——cf1208E

Posted zsben991126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树双tag+差分数组——cf1208E相关的知识,希望对你有一定的参考价值。

写了一上午

/*
对于每个数组a[],先排序然后从大到小把a[i]放进线段树更新
设a[i]的位置是pos,那么其可更新的区间是[pos,w-(li-pos)]
线段树结点保存
tag=now表示当前区间已经被更新满了,无需再往下更新 
flag=now表示当前区间被更新过
flag=now-1表示当前区间从未被更新过,可以直接进行覆盖  
*/
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define N 1000005
#define ll long long 
ll ans[N];
ll n,w;
struct Nodell pos,a;;
int cmp(Node a,Node b)return a.a>b.a;
vector<Node>v[N];
 
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int tag[N<<2],flag[N<<2],now;
void pushup(int rt)
    if(flag[rt<<1]==now || flag[rt<<1|1]==now)
        flag[rt]=now;
    if(tag[rt<<1]==now && tag[rt<<1|1]==now)
        tag[rt]=now;

void update(int L,int R,ll v,int l,int r,int rt)
    if(R<L)return;
    if(tag[rt]==now)return;//这个区间不用更新了0 
    if(L<=l && R>=r && flag[rt]!=now)
        ans[l]+=v;ans[r+1]-=v;
        flag[rt]=tag[rt]=now;
        return;
    
    int m=l+r>>1;
    if(L<=m)update(L,R,v,lson);
    if(R>m)update(L,R,v,rson);
    pushup(rt);

 
int main()
    cin>>n>>w;
    for(int i=1;i<=n;i++)
        int k;cin>>k;
        for(int j=1;j<=k;j++)
            Node t;
            scanf("%lld",&t.a);
            t.pos=j;
            v[i].push_back(t);
        
    
    
    for(int i=1;i<=n;i++)
        now=i;
        sort(v[i].begin(),v[i].end(),cmp);
        for(int j=0;j<v[i].size();j++)
            Node c=v[i][j];
            if(c.a<0)//开头结尾更新进0 
                update(1,w-v[i].size(),0,1,w,1);
                update(v[i].size()+1,w,0,1,w,1);
            
            update(c.pos,w-v[i].size()+c.pos,c.a,1,w,1);
        
        
    
    for(int i=1;i<=w;i++)ans[i]+=ans[i-1];
    for(int i=1;i<=w;i++)cout<<ans[i]<<" ";

 

以上是关于线段树双tag+差分数组——cf1208E的主要内容,如果未能解决你的问题,请参考以下文章

[LuoguP1438]无聊的数列(差分+线段树/树状数组)

线段树数组差分区间最大公约数

IncDec Sequence (差分)

Noip 2012 借教室 (二分答案+差分数组)

差分数组

第五讲 树状数组与线段树 未完结