首页 > 其他分享 >Codeforces Round 905 div2 F题

Codeforces Round 905 div2 F题

时间:2023-10-24 21:11:37浏览次数:31  
标签:info 905 int tr Codeforces maxn ans div2 minv

这是图片

记答案为\(ans_i\),表示从1到i次修改出现的字典序最小的数组a, \(c\)数组表示\(ans_i\)出现之后,所有修改的累加和。用一个vector存一下\(ans_i\)之后的所有修改。从1到q遍历每一次修改时,对\(c\)数组进行区间赋值操作,如果\(c\)数组中第一个不为0的数<0,那么\(ans_i\)加上\(c\)中的所有数,字典序会变得更小,所以将vector存的所有的区间赋值操作都加到\(ans_i\)上,并清空\(c\)数组。

使用两个维护区间最小值和最大值,可以区间赋值的线段树,其中一个维护\(ans_i\),另一个维护的是\(c\)数组,要找到\(c\)数组中第一个不为0的数,可以用线段树上二分实现

注意找第一个不为0的数需要同时维护最小值和最大值

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
const int N=5e5+10,INF=0x3f3f3f3f,mod=998244353;
int a[N],b[N];
struct info{
  ll minv,maxn;
   info(ll x=0):minv(x),maxn(x){}
   info operator+(info b){
       info c;
       c.minv=min(minv,b.minv);
       c.maxn=max(maxn,b.maxn);
       return c;
   }
};
struct node{
      int l,r;
      ll t;
      info val;     
};
void settag(node&u,ll t){
      u.val.minv+=t;
      u.val.maxn+=t;
      u.t+=t; 
} 
struct SegmentTree{
     vector<node>tr;
     SegmentTree(int n,int num[]):tr(n<<2){
        function<void(int,int,int)>build=[&](int u,int l,int r){
          if(l==r) {
            tr[u]={l,r,0,{num[l]}};
          }
          else {
             tr[u]={l,r,0};
             int mid=l+r>>1;
             build(u<<1,l,mid),build(u<<1|1,mid+1,r);
             pushup(u);
          }
        };
        build(1,1,n);
     }
     void pushdown(int u){
         if(tr[u].t){
             settag(tr[u<<1],tr[u].t);
             settag(tr[u<<1|1],tr[u].t);
             tr[u].t=0;
         }
     }
     void pushup(int u){
       tr[u].val=tr[u<<1].val+tr[u<<1|1].val;
     }
     void modify(int u,int l,int r,int t){
     if(tr[u].l>=l&&tr[u].r<=r){
           settag(tr[u],t);
     }
     else {
           pushdown(u);
           int mid=tr[u].l+tr[u].r>>1;
           if(l<=mid) modify(u<<1,l,r,t);
           if(r>mid) modify(u<<1|1,l,r,t);
           pushup(u); 
     }  
}  
     info query(int u,int l,int r){
        if(tr[u].l>=l&&tr[u].r<=r) return tr[u].val;
         else {
             pushdown(u);
             int mid=tr[u].l+tr[u].r>>1;
             if(r<=mid) return query(u<<1,l,r);
             else if(l>mid) return query(u<<1|1,l,r);
             else return query(u<<1,l,r)+query(u<<1|1,l,r);
         }
     }
     int find1(int u,ll x){
        if(tr[u].l==tr[u].r) return tr[u].val.maxn>x?tr[u].l:INF;
        else {
          pushdown(u);
          if(tr[u<<1].val.maxn>x) return find1(u<<1,x);
          else return find1(u<<1|1,x);     
        }
     }
       int find2(int u,ll x){
        if(tr[u].l==tr[u].r) return tr[u].val.minv<x?tr[u].l:INF;
        else {
          pushdown(u);
          if(tr[u<<1].val.minv<x) return find2(u<<1,x);
          else return find2(u<<1|1,x);     
        }
     }
};
void solve(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],b[i]=0;
    SegmentTree ans(n,a);
    SegmentTree c(n,b);

   //  for(int i=1;i<=n;i++) cout<<ans.query(1,i,i).minv<<" ";
   //  cout<<"\n";
    vector<array<int,3>>op;
    int q;
    cin>>q;
    while(q--){
       int l,r,x;
       cin>>l>>r>>x;
      op.push_back({l,r,x});
       c.modify(1,l,r,x);
       if(c.find1(1,0)>c.find2(1,0)){
      
          for(auto [u,v,m]:op) ans.modify(1,u,v,m),c.modify(1,u,v,-m);
          op.clear();
       }
   //  for(int i=1;i<=n;i++) cout<<ans.query(1,i,i).minv<<" ";
   //  cout<<"\n";
    }
    for(int i=1;i<=n;i++) cout<<ans.query(1,i,i).minv<<" ";
    cout<<"\n";

} 
int main()
{
      ios::sync_with_stdio(false);
      cin.tie(0),cout.tie(0);
      int T=1; 
      cin>>T;
      
      while(T--) solve();
     
    return 0;
}  

标签:info,905,int,tr,Codeforces,maxn,ans,div2,minv
From: https://www.cnblogs.com/yyyyyd/p/17785761.html

相关文章

  • 「解题报告」Codeforces Round 653 (Div. 3)
    A.RequiredRemainderYouaregiventhreeintegers\(x,y\)and\(n\).Yourtaskistofindthemaximuminteger\(k\)suchthat\(0\lek\len\)that\(k\bmodx=y\),where\(\bmod\)ismodulooperation.Manyprogramminglanguagesusep......
  • Codeforces Round 905 (Div. 2)
    Preface周日晚上Div1,2,3同乐,但我不想打Div1,同时第三个号由于只打了两场没够到Div2的门槛,因此刚好打不了Div2,遂玩了一晚上LOL今天补了下这场题感觉难度偏低,E之前的题都比较签,F刚开始没想到转化成差分最小准备去写扫描线+线段树了,后面发现其实可以写的很简单A.Chemistry签,设......
  • CodeForces 946F Fibonacci String Subsequences
    洛谷传送门CF传送门duel的时候差点不会2400了。套路地,考虑每个\(F(x)\)中与\(s\)相同的子序列的贡献。设这个子序列为\(F(x)_{p_1},F(x)_{p_2},F(x)_{p_3},\ldots,F(x)_{p_n}\)。我们想要它成为一个子序列的子串,那么\(F(x)_{[p_1,p_n]}\)中除了\(p_1\simp_......
  • Codeforces 1862G 题解
    传送门题解因为有这个操作:将序列\(a\)加上\(\{n,n-1,\cdots,1\}\),考虑差分。那么显然每次操作会将差分数组中的每个元素减去\(1\),如果差分数组中有\(0\),就会把\(0\)删除。所以可以发现差分数组中剩下的一定是操作前的最大值。由于操作后最大值还是最大值,最小值仍......
  • Codeforces Round 886 (Div. 4) 题解
    link我为什么还要vpdiv4场。。。A直接找最大的两个判断一下。voidsolve(){ inta[3]; cin>>a[0]>>a[1]>>a[2]; sort(a,a+3); if(a[2]+a[1]>=10)cout<<"YES\n"; elsecout<<"NO\n";}B按照题目意思模拟。voidsolv......
  • Codeforces Round#905 解题报告
    由于是解题报告不是过题报告,所以理所当然的放弃了后三题代码的写。感觉这场Div1D是cyh的菜,E是gjk的菜。我负责菜。只写Div1题的题解。A双指针可以做\(m=1\)你发现随便换\(a_1\)答案最多减少\(1\),而且\(a_1\)越趋向于减少,所以可以二分分割点B最短路,怎么dij......
  • Codeforces Round 905 (Div. 2) D1. Dances (Easy version)(贪心+二分)
    CodeforcesRound905(Div.2)D1.Dances(Easyversion)思路:对于\(a\),它的头默认为\(1\),则\(a_0\)=\(1\)对于排完序的\(a\)与\(b\)数组最优为从\(a\)的结尾删除,从\(b\)的开头删除二分保留位数,删去\(n-mid\)位,即\(a\)从\(0\)开始,\(b\)从\(k\)(\(k=n-......
  • 「解题报告」Codeforces Round 905 (Div. 3)
    A.MorningYouaregivenafour-digitpincodeconsistingofdigitsfrom\(0\)to\(9\)thatneedstobeentered.Initially,thecursorpointstothedigit\(1\).Inonesecond,youcanperformexactlyoneofthefollowingtwoactions:Pressthecu......
  • Codeforces Round 905 (Div. 2) C. You Are So Beautiful(数据结构)
    CodeforcesRound905(Div.2)C.YouAreSoBeautiful定义:设数组abcd子数组定义:从原数组砍去前面若干元素,后边若干元素,剩余的数组。如:bc、ab子序列定义:从原数组删除若干元素,剩余元素拼凑一起,组成的数组。如:ac、bd思路:作为结果的连续子数组,如果他为[\(a_l\),……,\(a_......
  • Educational Codeforces Round 144(CF1796 D~E) 题解
    D.MaximumSubarray题目链接十分钟秒了一道*2000,非常爽,但是个人感觉确实非常简单。下面令\(b_i=a_{i}-x\),\(b_i'=a_i+x\)。因为\(k<=20\),因此考虑一个复杂度与\(k\)相关的做法。不妨dp:设\(f_{i,j,0/1}\)表示考虑了前\(i\)个数,对\(j\)个数加上了\(x\),第\(i\)......