[P4145] 花神遊歷各國 - 線段樹
阿新 • • 發佈:2020-06-27
Description
維護序列,支援區間開方下取整,區間求和。
Solution
對線段樹上的每個 Node 記錄最大值 \(mx\)
修改操作時,若當前結點 \(mx=1\) 則不用繼續修改
(程式碼裡有很多冗餘的東西請手動忽略)
#include <bits/stdc++.h> using namespace std; #define int long long #define lc p*2,l,(l+r)/2 #define rc p*2+1,(l+r)/2+1,r #define NULLNODE {-1e18,1e18,0} const int N = 400005; int n,m,a[N],t1,t2,t3; struct Node { int mx,mn,sum; Node operator + (const Node &b) const { Node res; res.mn=min(mn,b.mn); res.mx=max(mx,b.mx); res.sum=sum+b.sum; return res; } bool ok() { return mx==1 || sum==mx; } void set(int x,int len) { mx=mn=x; sum=len*x; } }; Node node[N]; void build(int p,int l,int r) { if(l==r) { node[p].set(a[l],1); } else { build(lc); build(rc); node[p]=node[p*2]+node[p*2+1]; } } void modify(int p,int l,int r,int ql,int qr) { if(l>qr||r<ql) return; if(l>=ql&&r<=qr&&node[p].ok()) { node[p].set(sqrt(node[p].mx+0.1),r-l+1); } else { modify(lc,ql,qr); modify(rc,ql,qr); node[p]=node[p*2]+node[p*2+1]; } } Node query(int p,int l,int r,int ql,int qr) { if(l>qr||r<ql) return NULLNODE; if(l>=ql&&r<=qr) return node[p]; return query(lc,ql,qr)+query(rc,ql,qr); } signed main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; build(1,1,n); cin>>m; for(int i=1;i<=m;i++) { cin>>t1>>t2>>t3; if(t2>t3) swap(t2,t3); if(t1==0) { modify(1,1,n,t2,t3); } else { cout<<query(1,1,n,t2,t3).sum<<endl; } } }