Submission #1058093

#TimeUsernameProblemLanguageResultExecution timeMemory
1058093vjudge1Fish 2 (JOI22_fish2)C++17
100 / 100
574 ms17020 KiB
#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=1e9+3; const int base=350; const ll mod=998244353; int n,a[maxn],q; struct fentree { int st[maxn]; void Update(int u,int v) { u+=1; for(;u<=n+3;u+=u&-u) st[u]+=v; } int Get1(int u) { u+=1; int r=0; for(;u>0;u-=u&-u) r+=st[u]; return r; } int Get(int l,int r) {return Get1(r)-Get1(l-1);} }tree2; struct segtree1 { int mx[maxn*4]; void Update(int u,int v,int id=1,int l=0,int r=n+1) { // cerr<<u<<' ' << id<<' '<<l<<' '<<r<<'\n'; if (l==r) { mx[id]=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); mx[id]=max(mx[id*2],mx[id*2+1]); } int Lwalk(int u,int val,int id=1,int l=0,int r=n+1) { if (l==r) { if (mx[id]<=val) return-1; return l; } int mid=l+r>>1; if (u<=mid) return Lwalk(u,val,id*2,l,mid); int c=-1; if (mx[id*2+1]>val) c=Lwalk(u,val,id*2+1,mid+1,r); if (c!=-1) return c; if (mx[id*2] > val) return Lwalk(u,val,id*2,l,mid); else return -1; } int Rwalk(int u,int val,int id=1,int l=0,int r=n+1) { // if (u==5 && val==3) cerr<< id<<' '<<l<<' '<<r<<'\n'; if (l==r) { if (mx[id]<=val) return-1; return l; } int mid=l+r>>1; if (u>mid) return Rwalk(u,val,id*2+1,mid+1,r); int c=-1; // if (u==5 && val==3) cerr<<id<<' '<<mx[id*2]<<' '<<l<<' '<<mid<< " oday\n"; if (mx[id*2] > val) c=Rwalk(u,val,id*2,l,mid); if (c!=-1) return c; if (mx[id*2+1] > val) return Rwalk(u,val,id*2+1,mid+1,r); else return -1; } }tree1; struct segtree2 { int mn[maxn*4],st[maxn*4],lazy[maxn*4]; void push(int id) { int& x= lazy[id]; mn[id<<1]+=x; lazy[id<<1]+=x; mn[id<<1|1]+=x; lazy[id<<1|1]+=x; x=0; } pii Merge(pii l,pii r) { if (l.fi==r.fi) return {l.fi,l.se+r.se}; if (l.fi<r.fi) return {l.fi,l.se}; return {r.fi,r.se}; } void Build(int id=1,int l=1,int r=n) { if (l==r) { mn[id]=0; st[id]=1; return; } int mid=l+r>>1; Build(id*2,l,mid); Build(id*2+1,mid+1,r); pii x=Merge({mn[id*2],st[id*2]},{mn[id*2+1],st[id*2+1]}); mn[id]=x.fi,st[id]=x.se; } void Update(int u,int v,int val,int id=1,int l=1,int r=n) { if (u>r || v<l) return; if (u<=l && r<=v) { mn[id]+=val; lazy[id]+=val; return; } if (lazy[id]!=0) push(id); int mid=l+r>>1; Update(u,v,val,id<<1,l,mid); Update(u,v,val,id<<1|1,mid+1,r); pii x=Merge({mn[id*2],st[id*2]},{mn[id*2+1],st[id*2+1]}); mn[id]=x.fi,st[id]=x.se; } pii Get(int u,int v,int id=1,int l=1,int r=n) { if (u>r || v<l) return {inf,0}; if (u<=l && r<=v) return {mn[id],st[id]}; if (lazy[id]!=0) push(id); int mid=l+r>>1; return Merge(Get(u,v,id<<1,l,mid),Get(u,v,id<<1|1,mid+1,r)); } }tree3; vector<int> L,R; void Lget(int u) { L.clear(); L.pb(u-1); if (u==1) return; int id=u-2; while (id!=-1) { int sum=tree2.Get(id+1,u-1); if (a[id]>sum) L.pb(id); sum+=a[id]; id=tree1.Lwalk(id-1,sum); } } void Rget(int u) { R.clear(); R.pb(u+1); if (u==n) return; int id=u+2; while (id!=-1) { int sum=tree2.Get(u+1,id-1); if (a[id]>sum) R.pb(id); sum+=a[id]; id=tree1.Rwalk(id+1,sum); } } void Add(int i,int val) { Rget(i); Lget(i); for(int j:R) { if (j==i+1) continue; if (a[i]>tree2.Get(i+1,j-1)) { // cerr<< i<<' '<<j<<' '<<val<<'\n'; tree3.Update(i+1,j-1,val); } } for(int j:L) { if (j==i-1) continue; if (a[i]>tree2.Get(j+1,i-1)) { // cerr<< j<<' '<<i<<' '<<val<<'\n'; tree3.Update(j+1,i-1,val); } } int k,sum,last=0; for(int j:R) { for1(kk,last,L.size()-1) { k=L[kk]; sum=tree2.Get(k+1,j-1); if (sum>=a[j]) break; if (sum<a[j] && sum<a[k]) { // cerr<< k<<' '<<j<<' '<<val<<'\n'; last=kk; tree3.Update(k+1,j-1,val); } } } } void sol() { cin >> n; for1(i,1,n) cin >> a[i]; a[0]=a[n+1]=inf; for1(i,0,n+1) { tree1.Update(i,a[i]); tree2.Update(i,a[i]); } tree3.Build(); for1(i,0,n-1) { Rget(i); for(int j:R) { if (j==i+1) continue; if (a[i]>tree2.Get(i+1,j-1)) { // cerr<< i<<' '<<j<<" +1"<<'\n'; tree3.Update(i+1,j-1,1); } } } cin >> q; for1(_,1,q) { int t,l,r;cin >>t>>l>>r; if (t==1) { Add(l,-1); tree1.Update(l,r); tree2.Update(l,-a[l]+r); a[l]=r; Add(l,1); } else { Rget(l-1); Lget(r+1); int i=upper_bound(all(R),r)-R.begin()-1; i=R[i]; int j=upper_bound(all(L),l,greater<int>())-L.begin()-1; j=L[j]; cout << tree3.Get(i,j).se<<'\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 (stderr)

fish2.cpp: In member function 'void segtree1::Update(long long int, long long int, long long int, long long int, long long int)':
fish2.cpp:54:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   54 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In member function 'long long int segtree1::Lwalk(long long int, long long int, long long int, long long int, long long int)':
fish2.cpp:66:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   66 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In member function 'long long int segtree1::Rwalk(long long int, long long int, long long int, long long int, long long int)':
fish2.cpp:82:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   82 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In member function 'void segtree2::Build(long long int, long long int, long long int)':
fish2.cpp:119:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  119 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In member function 'void segtree2::Update(long long int, long long int, long long int, long long int, long long int, long long int)':
fish2.cpp:135:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  135 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In member function 'pii segtree2::Get(long long int, long long int, long long int, long long int, long long int)':
fish2.cpp:146:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  146 |         int mid=l+r>>1;
      |                 ~^~
fish2.cpp: In function 'void Add(long long int, long long int)':
fish2.cpp:8:34: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
    8 | #define for1(i,j,k) for(int i=j;i<=k;i++)
......
  204 |         for1(kk,last,L.size()-1)
      |              ~~~~~~~~~~~~~~~~~~   
fish2.cpp:204:9: note: in expansion of macro 'for1'
  204 |         for1(kk,last,L.size()-1)
      |         ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...