1. 程式人生 > >Educational Codeforces Round 41 E. Tufurama (961E)

Educational Codeforces Round 41 E. Tufurama (961E)

pri code 記錄 pan info clas ret for IT

技術分享圖片

【題解】

  第一眼看題飛快地想到一種做法,然後假掉了。

  這道題其實是主席樹的模板題來著。但是也有別的水法。

  我們可以發現每個位置的查詢區間是[1,min(a[i],i-1)],所以我們可以把查詢區間按照右端點排序。開一個權值樹狀數組記錄前i個a[i]的出現情況。我們從1到n按順序插入a[i],每個位置上都統計min(a[j],j-1)=i的j的答案。

  

技術分享圖片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rg register
 4 #define N 200010
 5 using namespace
std; 6 int n,a[N],b[N],d[N],t[N]; 7 long long ans; 8 inline int read(){ 9 int k=0,f=1; char c=getchar(); 10 while(c<0||c>9)c==-&&(f=-1),c=getchar(); 11 while(0<=c&&c<=9)k=k*10+c-0,c=getchar(); 12 return k*f; 13 } 14 inline void add(int x){ 15 for
(;x<=n;x+=(x&-x)) t[x]++; 16 } 17 inline int query(int x){ 18 int ret=0; for(;x>0;x-=(x&-x)) ret+=t[x]; return ret; 19 } 20 inline bool cmp(int x,int y){ 21 return d[x]<d[y]; 22 } 23 int main(){ 24 n=read(); 25 for(rg int i=1;i<=n;i++) a[i]=min(read(),n),b[i]=i,d[i]=min(a[i],i-1
); 26 sort(b+1,b+1+n,cmp); 27 for(rg int i=1,j=1;i<=n;i++){ 28 add(a[i]); 29 while(d[b[j]]<i&&j<=n) j++; 30 while(j<=n&&d[b[j]]==i) ans+=i-query(b[j++]-1); 31 } 32 printf("%I64d\n",ans); 33 return 0; 34 }
View Code

Educational Codeforces Round 41 E. Tufurama (961E)