• [Luogu 4231] 三步必杀


    [Luogu 4231] 三步必杀

    经某大佬的建议,蒟蒻去做了一下这道题,本人觉得这道题很有价值。

    题意概括:

    给定n个柱子,m次操作,每次操作会对l-r区间的损失度呈等差序列增加

    (已给定对l增加的损失度s和对r增加的损失度e)求在m次操作后n根柱子损失度的异或和与最大值。

     

    思路:

    一开始想了很久的数据结构,

    想过用树状数组,线段树等,

    但后来发现什么数据结构都不用。。

    因为是对一个区间加上等差数列,

    所以我们想到了差分

    即对l+1-r区间加,

    对l和r+1这两个点做单点加,

    可以用树状数组或线段树来维护,

    但还有一种更简单的解法,

    我们可以对这个差分序列再进行一次差分

    这样一来就是进行四个单点加

    分别是对l,l+1,r+1,r+2进行修改,

    最后再对差分序列的差分序列求前缀和

    得到的就是差分序列,

    再对差分序列求一次前缀和,

    得到的就是原数组。

    最后记得要开long long!

    <code>

    // luogu-judger-enable-o2
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define int long long 
    #define rep(i,n,m) for(i=n;i<=m;i++)
    int a[10000025],c[10000025];
    int read(){
        int w=0;char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') w=w*10+c-48,c=getchar();
        return w;
    }
    #undef int long long 
    int main(){
    #define int long long 
        int n,m,s,e,l,r,d,i,ans=0,maxn=0;
        n=read();m=read();
        rep(i,1,m){
            l=read();r=read();s=read();e=read();
            d=(e-s)/(r-l);
            a[l]+=s;a[l+1]+=d-s;
            a[r+1]+=-e-d;a[r+2]+=e;
        }
        rep(i,1,n){
            c[i]=c[i-1]+a[i];
            a[i]=a[i-1]+c[i];
            ans^=a[i];maxn=max(maxn,a[i]);
        }
        printf("%lld %lld",ans,maxn);
        return 0;
    } 
    Luogu 4231 三步必杀
  • 相关阅读:
    上下文切换
    NUMA的取舍与优化设置
    KVM CPU线程等学习记录
    openstack cpu pinning
    virt-install详解
    对KVM虚拟机进行cpu pinning配置的方法
    30 个 OpenStack 经典面试问题和解答
    OpenFace Docker 使用简介
    单链表、双链表及单链表的逆序
    Ubuntu14.04.1安装搜狗拼音输入法
  • 原文地址:https://www.cnblogs.com/Fish-/p/8450160.html
Copyright © 2020-2023  润新知