zoukankan      html  css  js  c++  java
  • [CF981E] Addition on Segments

    Description

    给定长度为 (n) 的序列,有 (q) 条操作,每条操作为将区间 ([l,r]) 加上 (x)。序列初始都为 (0)。问有多少个 $ k in [1,n]$ 满足能从 (q) 条操作中选出若干条操作后使得序列的最大值为 (k)

    Solution

    如果能有方案使得某个位置的值变成 (k),就一定存在方案使得最大值变为 (k)

    考虑一个暴力,对于每个位置分别考虑是否能使它变为 (k),设 (f[i][j]) 表示前 (i) 条操作中选取若干操作是否能使得该位置的和变为 (j),用 Bitset 优化,总时间复杂度 (O(frac 1 w n^2 q))

    考虑线段树分治,将 (q) 条操作中的每个区间拆分挂在线段树的若干结点上,然后将线段树 DFS 一遍,过程中利用结点上挂的区间来修改,历史记录用栈存储,这样回溯时可以撤销,到达叶子结点时即可得到当结点的答案。每次修改的复杂度为 (O(frac 1 w n)),最多有 (O(q log n)) 个拆分后的区间,故总时间复杂度为 (O(frac 1 w nq log n))

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    #define bst bitset<10005>
    const int N = 1000005;
    
    int n,q,l[N],r[N],x[N];
    vector <int> tg[N]; // Tags on segment tree nodes
    stack <bst> sta;
    bst ans;
    
    void modify(int p,int l,int r,int ql,int qr,int key)
    {
        if(l>qr || r<ql) return;
        if(l>=ql&&r<=qr)
        {
            tg[p].push_back(key);
        }
        else
        {
            modify(p*2,l,(l+r)/2,ql,qr,key);
            modify(p*2+1,(l+r)/2+1,r,ql,qr,key);
        }
    }
    
    void solve(int p,int l,int r)
    {
        bst now=sta.top();
        for(int i:tg[p])
        {
            now|=now<<i;
        }
        if(l==r)
        {
            ans|=now;
        }
        else
        {
            sta.push(now);
            solve(p*2,l,(l+r)/2);
            solve(p*2+1,(l+r)/2+1,r);
            sta.pop();
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin>>n>>q;
        for(int i=1;i<=q;i++)
        {
            cin>>l[i]>>r[i]>>x[i];
            modify(1,1,n,l[i],r[i],x[i]);
        }
    
        bst b0;
        b0[0]=1;
        sta.push(b0);
    
        solve(1,1,n);
    
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            if(ans[i]) ++cnt;
        }
        cout<<cnt<<endl;
        for(int i=1;i<=n;i++)
        {
            if(ans[i]) cout<<i<<" ";
        }
    }
    
    
  • 相关阅读:
    实验一框架选择及其分析
    站立会议(一)
    关于有多少个1的计算
    寻找水王问题
    如何买到更便宜的书
    NABCD
    二维数组首尾相连求最大子矩阵
    环数组求最大子数组的和
    二维数组求最大矩阵
    关于铁道大学基础教学楼电梯调查
  • 原文地址:https://www.cnblogs.com/mollnn/p/13631415.html
Copyright © 2011-2022 走看看