洛谷 P4145 上帝造題的七分鐘2 / 花神遊歷各國
阿新 • • 發佈:2018-09-03
pan www 復雜 是否 https math def con 代碼
洛谷
這題就是區間開根號,區間求和。我們可以分塊做。
我們記布爾數組vis[i]表示第i塊中元素是否全部為1。
因為顯然當一個塊中元素全部為1時,並不需要對它進行根號操作。
我們每個塊暴力開根號,因為數字最大\(2^31\),所以最多每個數字開幾次根號,所以時間復雜度很低。
記錄sum[i]表示第i塊的總和,所以我們得到這樣的算法:
當出現修改操作時,我們暴力修改,如果vis[i]為真,則不對該塊進行操作。
而出現查詢操作時,直接對正常操作再輸出即可。
代碼略醜:
#include <bits/stdc++.h> #define _ putchar('\n') using namespace std; typedef int _int; #define int long long const int N=100010; bool vis[N]; int n,m,a[N],len,num; int pos[N],sum[N],ll[N],rr[N]; inline void read(int &aa) { aa=0;char c=getchar(); for (;c>'9'||c<'0';c=getchar()); for (;c>='0'&&c<='9';c=getchar()) aa=(aa<<3)+(aa<<1)+(c^48); } char buffer[N],*S,*T; inline char Get_Char() { if (S==T) { T=(S=buffer)+fread(buffer,1,N,stdin); if (S==T) return EOF; } return *S++; } int Get_Int() { char c; int re=0; for (c=Get_Char();c<'0'||c>'9';c=Get_Char()); while (c>='0'&&c<='9') re=(re<<1)+(re<<3)+(c-'0'),c=Get_Char(); return re; } void print(int x) { if (x>9) print(x/10);putchar(x%10^48); } void build() { len=sqrt(n); num=n/len;if (n%len) ++num; for (int i=1;i<=num;++i) ll[i]=(i-1)*len+1,rr[i]=i*len; rr[num]=n; for (int i=1;i<=num;++i) for (int j=ll[i];j<=rr[i];++j) sum[i]+=a[j]; for (int i=1;i<=n;++i) pos[i]=(i-1)/len+1; } int ask(int l,int r) { int ans=0; if (pos[l]==pos[r]) { for (int i=l;i<=r;++i) ans+=a[i]; return ans; } for (int i=l;i<=rr[pos[l]];++i) ans+=a[i]; for (int i=pos[l]+1;i<pos[r];++i) ans+=sum[i]; for (int i=ll[pos[r]];i<=r;++i) ans+=a[i]; return ans; } void change(int l,int r) { if (pos[l]==pos[r]) { if (vis[pos[l]]) return; for (int i=l;i<=r;++i) { sum[pos[l]]-=a[i]; a[i]=sqrt(a[i]); sum[pos[l]]+=a[i]; } vis[pos[l]]=1; for (int i=ll[pos[l]];i<=rr[pos[l]];++i) if (a[i]>1) {vis[pos[l]]=0;break;} return; } if (!vis[pos[l]]) { for (int i=l;i<=rr[pos[l]];++i) { sum[pos[l]]-=a[i]; a[i]=sqrt(a[i]); sum[pos[l]]+=a[i]; } vis[pos[l]]=1; for (int i=ll[pos[l]];i<=rr[pos[l]];++i) if (a[i]>1) {vis[pos[l]]=0;break;} } if (!vis[pos[r]]) { for (int i=ll[pos[r]];i<=r;++i) { sum[pos[r]]-=a[i]; a[i]=sqrt(a[i]); sum[pos[r]]+=a[i]; } vis[pos[r]]=1; for (int i=ll[pos[r]];i<=rr[pos[r]];++i) if (a[i]>1) {vis[pos[r]]=0;break;} } for (int i=pos[l]+1;i<pos[r];++i) { if (vis[i]) continue; for (int j=ll[i];j<=rr[i];++j) { sum[i]-=a[j]; a[j]=sqrt(a[j]); sum[i]+=a[j]; } vis[i]=1; for (int j=ll[i];j<=rr[i];++j) if (a[j]>1) {vis[i]=0;break;} } } _int main() { n=Get_Int(); for (int i=1;i<=n;++i) a[i]=Get_Int(); build(); m=Get_Int(); int opt,l,r; while (m--) { opt=Get_Int(),l=Get_Int(),r=Get_Int(); if (l>r) swap(l,r); if (opt) print(ask(l,r)),_; else change(l,r); } return 0; }
洛谷 P4145 上帝造題的七分鐘2 / 花神遊歷各國