• 【POI2015】LOG


    题目链接

    首先猜一个结论:$sum a_ige c imes s$就可行。

    发现这个是显然错误的,因为有一些$a_ige s$,它们最多只有$c$的贡献。

    那么把这些数去掉,相应地减少$c$的值,接下来呢?

    我们发现这个结论成立了。

    有两种思路:

    我们把选数看作是填一个$c$列$s$行的表格,$i$可以填$a_i$次,限定同一下标不能填在同一行。因为$a_i<s$,所以直接依次按列填下去,一定不会冲突。这样下来“填满”也就是$sum a_ige c imes sLeftrightarrow$选数操作可行。

    固定$sum a_i$,当所有元素都是$s-1$时,元素个数最少,是$lceil dfrac{sum}{s-1} ceil$个,且我们有$sumge c imes s$,那么$$lceildfrac{sum}{s-1} ceil imes (s-1)ge sumge c imes s$$

    $$lceil dfrac{sum}{s-1} ceil ge c imesdfrac{s}{s-1}ge c$$

    发现一定有解。

    那么接下来就是用数据结构维护前缀计数和以及前缀和了。我这里用的是离散化之后的树状数组。注意前缀和树状数组要存原始值的和用来相乘。

    代码(100分):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #define IL inline
    #define RG register
    #define _1 first
    #define _2 second
    using namespace std;
    typedef long long LL;
    const int N=1e6;
    
        int n,m,a[N+3];
        
    struct Opt{
        int t,k,x,r;
    }p[N+3];
    
        int k,b[N+3];
        
    IL int sol(int x){
        int l=1,r=k,mid,ans;
        while(l<=r){
            mid=(l+r)>>1;
            if(x<=b[mid]){
                r=mid-1;    ans=mid;
            }
            else 
                l=mid+1;
            
        }
        return ans;
        
    }
        
    IL void discrete(){
        for(int i=1;i<=m;i++)
            b[i]=p[i].x;
        sort(b+1,b+m+1);
        
        k=1;
        for(int i=2;i<=m;i++)
        if(b[i]!=b[i-1])
            b[++k]=b[i];
        
        for(int i=1;i<=m;i++)
            p[i].r=sol(p[i].x);
        
    }
    
        LL sc[N+3],sx[N+3];
    
    IL int lowbit(int x){
        return x&(-x);
    }
    
    IL void mdf(LL *s,int p,LL x){
        for(;p<=k;p+=lowbit(p))
            s[p]+=x;
    }
    
    IL LL qry(LL *s,int p){
        LL ret=0;
        for(;p;p-=lowbit(p))
            ret+=s[p];
        return ret;
    }
    
        int c[N+3],x[N+3];
    
    IL void dat_init(){
        memset(c,0,sizeof 0);
        memset(sc,0,sizeof sc);
        memset(sx,0,sizeof sx);
        
    }
    
    int main(){
        scanf("%d%d
    ",&n,&m);
        for(int i=1;i<=m;i++){
            char ch;
            scanf("%c %d %d
    ",&ch,&p[i].k,&p[i].x);
            p[i].t=ch=='U'?1:2;
            
        }
        
        discrete();
        dat_init();
        for(int i=1;i<=m;i++)
        if(p[i].t==1){
            if(c[p[i].k]!=0){
                mdf(sc,c[p[i].k],-1);
                mdf(sx,c[p[i].k],-x[p[i].k]);
                
            }
            c[p[i].k]=p[i].r;
            x[p[i].k]=p[i].x;
            mdf(sc,c[p[i].k],1);
            mdf(sx,c[p[i].k],x[p[i].k]);
            
        }
        else {
            p[i].k-=qry(sc,k)-qry(sc,p[i].r-1);
            if(p[i].k<=0||qry(sx,p[i].r-1)>=1LL*p[i].k*p[i].x)
                printf("TAK
    ");
            else 
                printf("NIE
    ");
            
        }
    
        return 0;
    
    }
    View Code
  • 相关阅读:
    html中的浮动
    Html中元素的分类
    前端标签命名规范
    meta详解
    CSS的嵌套方法
    html标签
    W3C标准
    AE待整理
    AE小知识点备忘录
    Maximum Subarray
  • 原文地址:https://www.cnblogs.com/Hansue/p/12939990.html
Copyright © 2020-2023  润新知