zoukankan      html  css  js  c++  java
  • 新年快乐

    新年快乐

    维护⼀个序列 $a$ , 长度为 $n$ , 要求⽀持:

    $1.~1~ l~ r~ v$, 对区间 $[l, r]$ 中的每个数字都加上 $v$ 。

    $2.~2~ l~ r~ k$, 统计有多少个在区间 $[l, r]$ 中的数字满⾜他的值不超过$k$ 。


    Sol

    考虑分块,对于块内用个vector维护。

    单点改就暴力重建,整块就打标记。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<vector>
     8 #define maxn 200005
     9 #define ll long long
    10 using namespace std;
    11 int n,o,ans;
    12 ll a[maxn];
    13 struct node{
    14     int l,r,ne;
    15     ll bj;
    16     vector<ll>v;
    17 }s[1005];
    18 void ask(int id,ll v){
    19     if(s[id].ne){
    20         for(int i=s[id].l;i<=s[id].r;i++)a[i]+=s[id].bj;
    21         s[id].v.clear();
    22         for(int i=s[id].l;i<=s[id].r;i++)s[id].v.push_back(a[i]);
    23         sort(s[id].v.begin(),s[id].v.end());
    24         s[id].ne=0;s[id].bj=0;
    25     }
    26     int l=0,r=s[id].v.size()-1;
    27     while(l<r){
    28         int mid=l+r+1>>1;
    29         if(s[id].v[mid]+s[id].bj<=v)l=mid;
    30         else r=mid-1;
    31     }
    32     ans+=(s[id].v[l]+s[id].bj<=v)?l+1:l;
    33 }
    34 int main()
    35 {
    36     cin>>n;
    37     for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    38     int o=sqrt(n);
    39     for(int i=0;i<=n;i++){
    40         s[i].l=i*o;s[i].r=s[i].l+o-1;
    41         s[i].l=max(s[i].l,1);s[i].r=min(s[i].r,n);
    42         if(s[i].r==n)break;
    43         s[i].ne=1;
    44     }
    45     int m;cin>>m;
    46     for(int i=1,op,l,r;i<=m;i++){
    47         scanf("%d",&op);ll v;
    48         scanf("%d%d%lld",&l,&r,&v);
    49         if(op==1){
    50             int li=l/o,ri=r/o;
    51             for(int j=li+1;j<ri;j++)s[j].bj+=v;
    52             for(;l<s[li+1].l&&l<=r;l++)a[l]+=v;
    53             for(;r>s[ri-1].r&&r>=l;r--)a[r]+=v;
    54             s[li].ne=s[ri].ne=1;
    55         }
    56         else {
    57             int li=l/o,ri=r/o;ans=0;
    58             for(int j=li+1;j<ri;j++)ask(j,v);
    59             for(;l<s[li+1].l&&l<=r;l++)if(a[l]+s[li].bj<=v)ans++;
    60             for(;r>s[ri-1].r&&r>=l;r--)if(a[r]+s[ri].bj<=v)ans++;
    61             printf("%d
    ",ans);
    62         }
    63     }
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    网易2019校招C++研发工程师笔试编程题
    牛客网 数串
    ps aux 状态介绍
    阿里在线测评解析
    Ubuntu 18.04安装 Sublime
    file '/grub/i386-pc/normal.mod' not found.解决方案
    解决Windows10与Ubuntu系统时间不一致问题
    进程与线程的区别
    大端模式和小端模式
    2016湖南省赛----G
  • 原文地址:https://www.cnblogs.com/liankewei/p/10681047.html
Copyright © 2011-2022 走看看