zoukankan      html  css  js  c++  java
  • CF1208D Restore Permutation

    codeforces

    显然发现可以从右往左依次确定。

    考虑求出前缀和,每次查询当前位置上的值,然后删掉当前数,动态维护一下前缀和就好了

    对于查询值可以树状数组+二分(O(nlog^2n)),也可以线段树(O(nlog n))

    貌似树状数组+二分比线段树跑的要快

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    using namespace std;
    #define rg register
    void read(long long &x){
        char ch;bool ok;
        for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
        for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
    }
    const int maxn=2e5+10;
    int n,m,ans[maxn];long long f[maxn],a[maxn];
    #define lowbit(i) (i&(-i))
    void add(int x,int y){for(rg int i=x;i<=n;i+=lowbit(i))f[i]+=y;}
    long long get(int x){long long ans=0;for(rg int i=x;i;i-=lowbit(i))ans+=f[i];return ans;}
    bool check(int x,long long y){
        long long now=get(x);
        return now<=y;
    }
    int main(){
        scanf("%d",&n);
        for(rg int i=1;i<=n;i++)read(a[i]),add(i,i);
        for(rg int i=n;i;i--){
    	int l=1,r=n;
    	while(l<=r){
    	    int mid=(l+r)>>1;
    	    if(check(mid,a[i]))l=mid+1;
    	    else r=mid-1;
    	}
    	ans[i]=l;add(l,-l);
        }
        for(rg int i=1;i<=n;i++)printf("%d ",ans[i]);
    }
    
  • 相关阅读:
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
  • 原文地址:https://www.cnblogs.com/lcxer/p/11505886.html
Copyright © 2011-2022 走看看