SP2713 GSS4 題解
阿新 • • 發佈:2020-08-03
SP2713 GSS4 題解
間隙
雙倍經驗
前置知識:線段樹
如果您還不會線段樹的話,推薦去看一下這篇文章,我一開始也是在那裡學的
大致題意
給一堆數,有以下兩個操作:
-
給出一個區間\([L,R]\),把該區間內的每個數都開平方
-
給出一個區間\([L,R]\),查詢這個區間的每個數的和
分析
首先看一下這個資料範圍,\(1e18\),直接暴力的話肯定會T飛
求和操作很簡單,相信學過線段樹的人應該都會
難點在於這個開方操作,我們沒法像線段樹模板那樣打個懶標記來進行下傳操作
通過觀察\(\sqrt x\)函式影象緩慢的增長率或者其他性質不難發現,很多開方操作是不必要的,考慮減枝優化:
- 不難發現,當一個區間內的所有數都是\(1\)時,再對該區間進行開方操作對該區間內的總值造成不了任何改變(\(\sqrt{1} = 1\))
因此程式碼實現方面只要在區間內總值均為1的情況下加一個小剪枝即可
程式碼實現
思路理解了程式碼實現難度就不高了,但還是有幾個坑點...具體的註釋裡有寫
#include<bits/stdc++.h> #define lson (node<<1)//左兒子 #define rson (node<<1|1)//右兒子 #define ll long long #define int long long //記得開long long using namespace std; const int MAXN = 100005; struct st{ int l,r;//左右端點 ll sum; }tree[MAXN<<2]; ll a[MAXN]; int n,m; void pushup(int node){ tree[node].sum = tree[lson].sum + tree[rson].sum;//合併操作 } void build(int node,int l,int r){//建樹 tree[node].l = l; tree[node].r = r; if(l==r){ tree[node].sum = a[l]; return; } int mid = (l+r)>>1; build(lson,l,mid); build(rson,mid+1,r); pushup(node); } void change(int node,int l,int r){ int L = tree[node].l,R = tree[node].r; if(tree[node].sum==R-L+1) return;//如果總和為區間長度,也就是所有值均為1時,直接剪枝掉 if(L==R){ tree[node].sum = sqrt(tree[node].sum); return; } int mid = (L+R)>>1; if(l<=mid){ change(lson,l,r); } if(r>mid){ change(rson,l,r); } pushup(node); } ll query(int node,int l,int r){//查詢 int L = tree[node].l,R = tree[node].r; if(l<=L&&r>=R){//包含在查詢區間內,直接返回sum值 return tree[node].sum; } int mid = (L+R)>>1; ll ans = 0; if(l<=mid){ ans+=query(lson,l,r); } if(r>mid){ ans+=query(rson,l,r); } return ans; } signed main(){ ios::sync_with_stdio(false);//不加貌似會TLE? cin.tie(0); cout.tie(0); int Case=0; while(cin>>n){ printf("Case #%d:\n",++Case);//注意,樣例裡那個case是要輸出的,一開始被這裡卡了好久... memset(a,0,sizeof(a));//記得要先memset memset(tree,0,sizeof(tree)); for(int i=1;i<=n;i++){ cin>>a[i]; } build(1,1,n); cin>>m; while(m--){ int mode,left,right; cin>>mode>>left>>right; if(left > right){ swap(left,right); } if(mode==0){ change(1,left,right); } else{ printf("%lld\n",query(1,left,right)); } } puts("");//記得換行 } }