답안 #1055700

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1055700 2024-08-13T03:49:02 Z vjudge1 Fish 2 (JOI22_fish2) C++17
0 / 100
28 ms 79956 KB

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define for1(i,j,k) for(int i=j;i<=k;i++)
#define for2(i,j,k) for(int i=j;i>=k;i--)
#define for3(i,j,k,l) for(int i=j;i<=k;i+=l)
#define bit(n,i) ((n>>i)&1)
#define all(x) x.begin(),x.end()
#define int long long
typedef long long ll;
typedef pair<int,int> pii;
typedef double ld;
typedef pair<ld,ld> pdd;
typedef pair<ll,ll> pll;
const ll maxn=1e5+69;
const ll offset=2e5;
const ll inf=1e18;
const int base=350;
const ll mod=998244353;
int n,q,a[maxn];
struct Node
{
    int pre,mid,suf,sum,sz;
    vector<pii> vl,vr; //{prefix sum[i], i+1}
    void clear()
    {
        pre=mid=suf=sum=sz=0;
        vl.clear(),vr.clear();
    }
};
struct Segtree
{
    Node st[maxn*4];
    int li[maxn*4],ri[maxn*4];
    void Merge(int id,int l,int r)
    {
        int pre,mid,suf,sum,sz;
        vector<pii> vl,vr;
        if (l==-1)
        {
            st[id]=st[r];
            return;
        }
        else if (r==-1)
        {
            st[id]=st[l];
            return;
        }
//        st[id].clear();
        sum=st[l].sum + st[r].sum;
        sz=st[l].sz + st[r].sz;
        vl=st[l].vl;
        for(pii x:st[r].vl) if (x.fi + st[l].sum< a[x.se]) vl.pb({x.fi + st[l].sum, x.se});
        vr=st[r].vr;
        for(pii x:st[l].vr) if (x.fi + st[r].sum< a[x.se]) vr.pb({x.fi + st[r].sum, x.se});
        if (vl.size()> st[l].vl.size())
        {
            pre=st[l].sz + vl.back().se -li[r];
            mid=st[r].mid;
            suf=st[r].suf;
            st[id]={pre,mid,suf,sum,sz,vl,vr};
            return;
        }
//        if (id==0)cerr<<"im here bro\n";
        if (vr.size()> st[r].vr.size())
        {
            pre=st[l].pre;
            mid=st[l].mid;
            suf=st[r].sz + ri[l] - vr.back().se;
//            cerr<< "gg "<< vr.back().se<<'\n';
            st[id]={pre,mid,suf,sum,sz,vl,vr};
            return;
        }
//        if (id==0)cerr<<"im here bro 2\n";
        pre=st[l].pre;
        suf=st[r].suf;
        mid=st[l].mid + st[r].mid;
        int i=0,j=0,bonus=0;
        while (i<st[l].vr.size() && j<st[r].vl.size())
        {
            int sum= st[l].vr[i].fi + st[r].vl[j].fi, id1=st[l].vr[i].se, id2=st[r].vl[j].se;
            if (sum < a[id1] && sum < a[id2])
            {
                bonus=id2-id1-1;
//                cerr<< id<<' '<<l <<' '<<st[l].vr[i].se<<'\n';
                if (st[l].vr.size()-i > st[r].vl.size()-j) i++;
                else j++;
                continue;
            }
            if (sum>=a[id1]) i++;
            else if (sum>=a[id2]) j++;
        }
        mid+=bonus;
        st[id]={pre,mid,suf,sum,sz,vl,vr};
    }
    void Build(int id=1,int l=1,int r=n)
    {
        li[id]=l,ri[id]=r;
        if (l==r)
        {
            st[id].clear();
            st[id].sz=1;
            st[id].sum=a[l];
            st[id].vl.pb({0,l});
            st[id].vr.pb({0,l});
//            cerr<< l<<'\n';
            return;
        }
        int mid=l+r>>1;
        Build(id*2,l,mid);
        Build(id*2+1,mid+1,r);
        Merge(id,id*2,id*2+1);
//        cerr<< id<<' '<<l<<' '<<r<<":\n";
//        cerr<<st[id].suf<<'\n';
    }
    void Update(int u,int v,int id=1,int l=1,int r=n)
    {
        if (l==r)
        {
            a[l]=v;
            st[id].sum=v;
            return;
        }
        int mid=l+r>>1;
        if (u<=mid) Update(u,v,id*2,l,mid);
        else Update(u,v,id*2+1,mid+1,r);
        Merge(id,id*2,id*2+1);
    }
    void Get(int u,int v,int id=1,int l=1,int r=n)
    {
        if (u>r || v<l) return;
        if (u<=l && r<=v)
        {
            if (st[0].sz==0)
            {
                Merge(0,-1,id);
                li[0]=li[id];
            }
            else Merge(0,0,id);
            ri[0]=ri[id];
            return;
        }
        int mid=l+r>>1;
        Get(u,v,id*2,l,mid);
        Get(u,v,id*2+1,mid+1,r);
    }
    int Get_ans(int id){return st[id].sz-st[id].mid- st[id].pre-st[id].suf;}

}tree;


void sol()
{
    cin >> n;
    for1(i,1,n) cin  >> a[i];
    tree.Build();
//    cout << tree.Get_ans(1);
    cin >> q;
    for1(i,1,q)
    {
        int t,l,r;cin >>t>>l>>r;
        if (t==1)
        {
            tree.Update(l,r);
        }
        else
        {
            tree.st[0].clear();
            tree.Get(l,r);
            cout << tree.Get_ans(0)<<'\n';
        }
    }
}
int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    freopen("fish2.inp","r",stdin);
    freopen("fish2.out","w",stdout);

    int t=1;//cin >> t;
    while (t--) {
        sol();
    }
}

/*
4 12
1 2 3
1 3
2 3
2 1
1 2
1 2
1 4
1 1
1 1
2 4
2 3
1 1
3 4



*/



Compilation message

fish2.cpp: In member function 'void Segtree::Merge(long long int, long long int, long long int)':
fish2.cpp:83:17: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   83 |         while (i<st[l].vr.size() && j<st[r].vl.size())
      |                ~^~~~~~~~~~~~~~~~
fish2.cpp:83:38: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   83 |         while (i<st[l].vr.size() && j<st[r].vl.size())
      |                                     ~^~~~~~~~~~~~~~~~
fish2.cpp: In member function 'void Segtree::Build(long long int, long long int, long long int)':
fish2.cpp:113:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  113 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In member function 'void Segtree::Update(long long int, long long int, long long int, long long int, long long int)':
fish2.cpp:128:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  128 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In member function 'void Segtree::Get(long long int, long long int, long long int, long long int, long long int)':
fish2.cpp:147:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  147 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In function 'int32_t main()':
fish2.cpp:181:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  181 |     freopen("fish2.inp","r",stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
fish2.cpp:182:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  182 |     freopen("fish2.out","w",stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Runtime error 28 ms 79956 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 27 ms 79884 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 28 ms 79956 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 27 ms 79884 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 27 ms 79884 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 28 ms 79956 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -