Lost Cows POJ
阿新 • • 發佈:2019-01-04
需要用樹狀陣列維護01序列字首和,並且查詢某個位置的字首和是k,也就是前面有k個1
這個可以用二分,兩個log,但是用倍增就是一個log
不得不說樹狀陣列和倍增的相性真的很好,倍增到的節點維護資訊與上一級完全沒有重合
譬如說跳8可以跳到8,跳4的時候如果可以跳12直接加上c[12]就可以,因為c[12]維護的是c[9]到c[12]
#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<stack> #include<set> #include<map> #include<vector> #include<iomanip> #include<bitset> using namespace std; // #define ll long long #define ull unsigned long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) #define sqr(a) (a)*(a) #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)) ll qp(ll a,ll b,ll mod){ ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t; } struct DOT{ll x;ll y;}; inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} const int dx[4]={0,0,-1,1}; const int dy[4]={1,-1,0,0}; const int inf=0x3f3f3f3f; const ll Linf=0x3f3f3f3f3f3f3f3f; const ll mod=1e9+7;; const int maxn=1e5+34; int n; int a[maxn],b[maxn],c[maxn*2],h[maxn]; int lowbit(int x){return x&-x;} int ask(int x){ int ans=0; for(;x;x-=lowbit(x))ans+=c[x]; return ans; } void add(int x,int y){ for(;x<=n;x+=lowbit(x))c[x]+=y; } int main(){ scanf("%d",&n); for(int i=2;i<=n;i++){scanf("%d",&a[i]);} for(int i=1;i<=n;i++){b[i]=1;add(i,1);} int lim=(int)log2(n); for(int i=n;i>=1;i--){ int ans=0,sum=0; for(int p=lim;p>=0;p--){ if(ans + (1<<p) <=n && sum+c[ans+(1<<p)]<=a[i]){ sum+=c[ans+(1<<p)]; ans+=(1<<p); } } h[i]=ans+1; add(ans+1,-1); } for(int i=1;i<=n;i++)printf("%d\n",h[i]); }