[POI2015]LOG

Posted owencodeisking

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POI2015]LOG相关的知识,希望对你有一定的参考价值。

今天考试考了这题,所以来贡献([POI2015]LOG)的第一篇题解。代码略丑,调了快三个小时才调出来(AC)代码。

对于这种小清新数据结构题,所以我觉得树状数组才是这道题的正确打开方式。

首先离散化,这样才不会爆内存。开两个树状数组,第一个树状数组记录离散化后(1)(i)中数字出现的个数,第二个树状数组离散化前(1)(i)数字出现值的和。把所有询问都读入进来,对于每次操作:

操作(1):单点修改,若之前的数是正数,第一个树状数组(-1),第二个树状数组(-)原来的数,若之后的数是正数,第一个树状数组(+1),第二个树状数组(+)之后的数

操作(2):区间询问,先将大于(s)的个数求出来,再比较(c-)大于(s)的个数乘上(c)与剩余数之和,若前者大,输出(NIE),否则输出(TAK)

再开一个数组记录当前序列的值,就完事了

(Code Below:)

#include <bits/stdc++.h>
#define ll long long
#define res register
using namespace std;
const ll maxn=1000000+10;
ll n,m,a[maxn],b[maxn],mp[maxn],tot,num;
//a[i]是目前的序列情况,b[i]是第几次修改后离散化1-num,mp记录离散化后的数组1-1e9
//tot是几次修改,num是离散化后的修改,c1[i]是1-i的个数,c2[i]是1-i的值的和 
ll c1[maxn],c2[maxn];
struct node{
    ll k,x,id;
}q[maxn];
//id是第几次修改 
inline ll read(){
    res ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return (f==1)?x:-x;
}
ll lowbit(ll x){return x & (-x);}
void add_num(ll x,ll y){
    for(;x<maxn;x+=lowbit(x))
        c1[x]+=y;   
}
void add_sum(ll x,ll y){
    for(;x<maxn;x+=lowbit(x))
        c2[x]+=y;
}
ll query_num(ll x){
    ll ans=0;
    for(;x>0;x-=lowbit(x))
        ans+=c1[x];
    return ans;
}
ll query_sum(ll x){
    ll ans=0;
    for(;x>0;x-=lowbit(x))
        ans+=c2[x];
    return ans;
}

int main()
{
    n=read(),m=read();
    res ll k,x,c,s;char ch=getchar();
    for(ll i=1;i<=m;i++){
        while(ch!='U'&&ch!='Z') ch=getchar();
        q[i].k=read(),q[i].x=read();
        if(ch=='U') {
            q[i].id=++tot;
            b[tot]=mp[tot]=q[i].x;
        }
        else q[i].id=-1;
        if(i!=m) ch=getchar();
    }
    sort(mp+1,mp+tot+1);
    num=unique(mp+1,mp+tot+1)-mp-1;
    for(ll i=1;i<=tot;i++)
        b[i]=lower_bound(mp+1,mp+num+1,b[i])-mp;
    for(ll i=1;i<=m;i++)
        if(q[i].id!=-1) q[i].x=b[q[i].id];
    for(ll i=1;i<=m;i++){
        if(q[i].id!=-1){//q[i].x被离散化 
            if(a[q[i].k]>0){
                ll real=lower_bound(mp+1,mp+num+1,a[q[i].k])-mp;
                add_num(real+1,-1);
                add_sum(real+1,-a[q[i].k]);
            }
            a[q[i].k]=mp[q[i].x];
            if(mp[q[i].x]>0){
                add_num(q[i].x+1,1);
                add_sum(q[i].x+1,mp[q[i].x]);
            }
        }
        else {//q[i].x没被离散化,real是去q[i].x在mp中的位置 
            ll real=upper_bound(mp+1,mp+num+1,q[i].x)-mp-1;
            ll bigans=query_num(maxn+1)-query_num(real+1);
            ll smallans=query_sum(real+1);
            if(smallans>=(q[i].k-bigans)*q[i].x) printf("TAK
");
            else printf("NIE
");
        }
    }
    return 0;
}

以上是关于[POI2015]LOG的主要内容,如果未能解决你的问题,请参考以下文章

[POI2015]LOG

P3586 [POI2015]LOG

webstorm代码片段的创建

按钮在片段中不起作用

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

[POI2015]PUS