zoukankan      html  css  js  c++  java
  • Permutacja

    题意:

    要求动态求问是否有一个 1~n 的排列,使得满足 $p_i leq a_i$,给定 $a_i$ 初始值,接下来 m次单个位置修改,每次求问是否可以构造出来。

    解法:

    构造一序列使得 $cnt_i$ 表示 $a$ 序列当前 i 的个数,记 $suffix(i)$ 为此序列的后缀和。

    那么可以构造出序列 <-> $ 0 leq suffix(i) - (n-i+1)$,建权值线段树维护 $suffix(i) - (n-i+1)$ 即可。

    #include <bits/stdc++.h>
    
    #define l(x) ch[x][0]
    #define r(x) ch[x][1]
    #define LL long long
    
    const int N = 200010;
    
    using namespace std;
    
    int totn,n,a[N];
    int ch[N<<1][2];
    LL minv[N<<1],addv[N<<1];
    
    void update(int x)
    {
        minv[x] = min(minv[l(x)], minv[r(x)]);
    }
    
    void push(int x)
    {
        if(addv[x]==0) return;
        addv[l(x)] += addv[x], minv[l(x)] += addv[x];
        addv[r(x)] += addv[x], minv[r(x)] += addv[x];
        addv[x] = 0;
    }
    
    int build(int l,int r)
    {
        int x = ++totn;
        addv[x] = 0;
        if(l==r)
        {
            l(x) = r(x) = 0;
            minv[x] = -l;
            return x;
        }
        int mid = (l+r)>>1;
        l(x) = build(l,mid);
        r(x) = build(mid+1,r);
        update(x);
        return x;
    }
    
    void add(int x,int l,int r,int ql,int qr,LL qv)
    {
        
        push(x);
        if(ql<=l && r<=qr)
        {
            addv[x] = qv;
            minv[x] += qv;
            return ;
        }
        int mid = (l+r)>>1;
        if(ql<=mid) add(l(x),l,mid,ql,qr,qv);
        if(mid<qr)  add(r(x),mid+1,r,ql,qr,qv);
        update(x);
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            a[i] = n-a[i]+1;
        }
        build(1,n);
        for(int i=1;i<=n;i++) add(1,1,n,a[i],n,1); 
        int m;
        scanf("%d",&m);
        if(minv[1]>=0) puts("TAK");
        else puts("NIE");
        for(int i=1,x,v;i<=m;i++)
        {
            scanf("%d%d",&x,&v);
            v = n-v+1;
            add(1,1,n,a[x],n,-1);
            add(1,1,n,v,n,1);
            a[x] = v;
            if(minv[1]>=0) puts("TAK");
            else puts("NIE");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【ContestHunter】【弱省胡策】【Round2】
    PKUSC滚粗记
    【BZOJ】【3157】&【BZOJ】【3516】国王奇遇记
    【BZOJ】【2219】数论之神
    【POJ】【2601】Simple calculations
    【POJ】【1635】Subway Tree Systems
    【POJ】【2449】Remmarguts' Date
    【BZOJ】【1004】【HNOI2008】Cards
    【Burnside定理】&【Pólya定理】
    【Tsinsen】【A1365】森林旅店
  • 原文地址:https://www.cnblogs.com/lawyer/p/7197142.html
Copyright © 2011-2022 走看看