zoukankan      html  css  js  c++  java
  • atcoder square869120Contest#3 F 寿司

    省选round1的时候dalao的推荐——atcoder的题目码量不大,但很巧妙,题目比较难找,挂个链冷静一下:http://s8pc-3.contest.atcoder.jp/tasks/s8pc_3_f

    还行吧。。。

    好久没写标记下传的线段树了(这次一写就是个双标记)居然能一遍写对核心代码(没开longlongRE了一发,改longlong就A了)

    因为本来都是0,就好处理了

    对于这道题我的理解是灌水(水泥):每次在a的地方灌b体积的水,如果平就往左灌

    感性理解得到单调性(数学归纳可证),而且被灌的地方分成三个阶段:先填平,再竖直向上涨,最后在左边的一段填1

    二分填到哪里位置,然后直接(用线段树)模拟就可以了,复杂度两个log

     1 #include <bits/stdc++.h>
     2 #define sum(x,y) que(1,1,n,x,y)
     3 #define change(x,y,z) chan(1,1,n,x,y,z)
     4 #define add(x,y,z) Plus(1,1,n,x,y,z)
     5 #define mid (l+r>>1)
     6 using namespace std;
     7 long long sum[400000],fg[400000],ad[400000];
     8 long long n,m,a,b; 
     9 void down(int now,int l,int r)
    10 {
    11     if(fg[now])
    12     {
    13         fg[now]+=ad[now];
    14         fg[now<<1]=fg[now];
    15         fg[now<<1|1]=fg[now];
    16         ad[now]=ad[now<<1]=ad[now<<1|1]=fg[now]=0;
    17         sum[now<<1]=fg[now<<1]*(mid-l+1);
    18         sum[now<<1|1]=fg[now<<1|1]*(r-mid);
    19     }
    20     if(ad[now])
    21     {
    22         ad[now<<1]+=ad[now];
    23         ad[now<<1|1]+=ad[now];
    24         sum[now<<1]+=ad[now]*(mid-l+1);
    25         sum[now<<1|1]+=ad[now]*(r-mid);
    26         ad[now]=0; 
    27     }
    28 }
    29 void updata(int now)
    30 {
    31     sum[now]=sum[now<<1]+sum[now<<1|1];
    32 }
    33 void chan(int now,int l,int r,int x,int y,long long z)
    34 {
    35     if(l==x && r==y)
    36     {
    37         fg[now]=z;
    38         ad[now]=0;
    39         sum[now]=z*(r-l+1);
    40         return;
    41     }
    42     down(now,l,r);
    43     if(x<=mid)
    44         chan(now<<1,l,mid,x,min(mid,y),z);
    45     if(y>mid)
    46         chan(now<<1|1,mid+1,r,max(mid+1,x),y,z);
    47     updata(now);
    48 }
    49 void Plus(int now,int l,int r,int x,int y,long long z)
    50 {
    51     if(l==x && r==y)
    52     {
    53         ad[now]+=z;
    54         sum[now]+=z*(r-l+1);
    55         return;
    56     }
    57     down(now,l,r);
    58     if(x<=mid)
    59         Plus(now<<1,l,mid,x,min(mid,y),z);
    60     if(y>mid)
    61         Plus(now<<1|1,mid+1,r,max(mid+1,x),y,z);
    62     updata(now);
    63 }
    64 long long que(int now,int l,int r,int x,int y)
    65 {
    66     if(l==x && r==y)
    67         return sum[now];
    68     down(now,l,r);
    69     long long ret=0;
    70     if(x<=mid)
    71         ret+=que(now<<1,l,mid,x,min(y,mid));
    72     if(y>mid)
    73         ret+=que(now<<1|1,mid+1,r,max(x,mid+1),y);
    74     return ret;
    75 }
    76 int main()
    77 {
    78     scanf("%d%d",&n,&m);
    79     for(int i=1;i<=m;i++)
    80     {
    81         scanf("%d%lld",&a,&b);
    82         int l=1,r=a;
    83         for(;l<r;)
    84             if(sum(mid,mid)*(a-mid+1)-sum(mid,a)<=b)
    85                 r=mid;
    86             else
    87                 l=mid+1;
    88         b-=sum(l,l)*(a-l+1)-sum(l,a);
    89         change(l,a,sum(l,l));
    90         add(l,a,b/(a-l+1));
    91         if(b%(a-l+1))
    92         add(l,l+b%(a-l+1)-1,1);
    93     }
    94     for(int i=1;i<=n;i++)
    95         printf("%lld
    ",sum(i,i));
    96     return 0;
    97 }
  • 相关阅读:
    Leetcode 257. 二叉树的所有路径
    Leetcode 1306. 跳跃游戏 III
    Leetcode 编程中好用的一些C++用法
    Leetcode 96. 不同的二叉搜索树
    Leetcode 892. 三维形体的表面积
    Leetcode 219. 存在重复元素 II
    Leetcode 5281. 使结果不超过阈值的最小除数
    springboot多租户设计
    MAC电脑修改Terminal以及vim高亮显示
    基于springboot搭建的web系统架构
  • 原文地址:https://www.cnblogs.com/wanglichao/p/6830908.html
Copyright © 2011-2022 走看看