zoukankan      html  css  js  c++  java
  • codeforces-915E.-Physical Education Lessons

    codeforces-915E.-Physical Education Lessons

    传送门:https://codeforces.com/contest/915/problem/E

    题意:

    有n天工作日1-n,q个指令

    每个指令有三个参数 l,r,k

    如果 k=1,那么从 l到 r (包含端点)的所有日子都变成非工作日。
    如果 k=2,那么从 l 到 r(包含端点)的所有日子都变成工作日。

    统计每个指令下发后,剩余的工作日天数。

    目测 线段树裸题 但在洛谷上看到有大佬们用平衡树 ,珂朵莉树 ,动态开点等等等神奇算法,但我还都 没有学,感兴趣的可以去看看   https://www.luogu.com.cn/problemnew/solution/CF915E

    但是数据范围很大  1<=n<=1e9      1<=q<=3e5

    可以发现 我们建不出4e9的数组

    但是能开的出4*2*3e5的(只存每段区间的两个坐标,因为是两个坐标,要再开大一倍,不然会wa17),离线解决这个问题

    所以要加一个离散化

    我用的是vector 排序 去重 再用二分查询 用map和unorder_map应该会tle

    可能我太菜了吧 零零散散连玩带改改了小半天

    先把数据读入放入vector 离散化,注意在存左右坐标的时候把r++,这样 l==r 时 能把那个距离抻出来,不然的话,这个距离就没了

    然后还要记一个ans为1~n中没有被ve[0]~ve[ve.size()-1] 覆盖到的值,这样的值就是1,没有被改变过

    然后就是一个区间更新的线段树 

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lowbit(a) ((a)&-(a))
    #define clean(a,b) memset(a,b,sizeof(a))
    const int mod = 1e9 + 7;
    const int inf=0x3f3f3f3f;
    const int maxn = 3e5+10;
     
    inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
    int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}
     
    int _;
    vector<int>ve;
     
     int getid(int x){return lower_bound(ve.begin(),ve.end(),x)-ve.begin()+1;}
    //////////////////////////////////////////////////////////////////////////
    struct node
    {
        int l,r,sum,add,vis;
    }tree[maxn*8];
    struct node1
    {
        int l,r,k;
    }q[maxn];
    int cnt;
    
    void push_down(int root)
    {
        if(tree[root].add==1)//1
        {
            tree[root<<1].sum=ve[tree[root<<1].r]-ve[tree[root<<1].l-1];
            tree[root<<1|1].sum=ve[tree[root<<1|1].r]-ve[tree[root<<1|1].l-1];
            tree[root<<1].vis=1;
            tree[root<<1|1].vis=1;
            tree[root<<1].add=1;
            tree[root<<1|1].add=1;
        }
        else //0
        {
            tree[root<<1].sum=0;
            tree[root<<1|1].sum=0;
            tree[root<<1].vis=1;
            tree[root<<1|1].vis=1;
            tree[root<<1].add=0;
            tree[root<<1|1].add=0;
        }
        tree[root].vis=0;
        tree[root].add=0;
    }
    void build(int l,int r,int root)
    {
        tree[root].l=l;
        tree[root].r=r;
        if(l==r)
        {
            tree[root].sum=ve[l]-ve[l-1];
            return ;
        } 
        int mid=(l+r)>>1;
        build(l,mid,root<<1);
        build(mid+1,r,root<<1|1);
        tree[root].sum=tree[root<<1|1].sum+tree[root<<1].sum;
    }
    
    void update(int l,int r,int k,int root)
    {
        if(tree[root].l==l&&tree[root].r==r)
        {
            if(k==1) tree[root].sum=0,tree[root].add=0;
            else if(k==2) tree[root].sum=ve[r]-ve[l-1],tree[root].add=1;
            tree[root].vis=1;
            return ;
        }
        if(tree[root].vis) push_down(root);
        int mid=(tree[root].l+tree[root].r)>>1;
        if(r<=mid) update(l,r,k,root<<1);
        else if(l>mid) update(l,r,k,root<<1|1);
        else 
        {
            update(l,mid,k,root<<1);
            update(mid+1,r,k,root<<1|1);
        }
        tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
    }
    //////////////////////////////////////////////////////////////////////////
     
    int main()
    {
        // freopen("in.in","r",stdin);
        int n=read();
        int m=read();
        int l,r,k;
        for(int i=1;i<=m;i++)
        {
            q[i].l=read(),q[i].r=read(),q[i].k=read();
            q[i].r++;
            ve.push_back(q[i].l);
            ve.push_back(q[i].r);
        }
        sort(ve.begin(),ve.end());
        ve.erase(unique(ve.begin(),ve.end()),ve.end());
        int ans=ve[0]-1+n-ve[ve.size()-1]+1;
        build(1,ve.size()-1,1);
        for(int i=1;i<=m;i++)
        {
            update(getid(q[i].l),getid(q[i].r)-1,q[i].k,1);
            printf("%d
    ",tree[1].sum+ans);
        }
        return 0;
    }
  • 相关阅读:
    日常小算法
    美化type="file"控件
    流文件_从网络中获取文件
    Kibana配置安装
    JDK安装
    Node.js安装windows环境
    RabbitMQ高可用
    RabbitMQ实例C#
    RabbitMQ基础命令rabbitmqctl
    RabbitMQ配置
  • 原文地址:https://www.cnblogs.com/YangKun-/p/12748325.html
Copyright © 2011-2022 走看看