码迷,mamicode.com
首页 > 其他好文 > 详细

[POI2015]LOG

时间:2018-08-25 20:01:43      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:else   getc   原来   amp   pac   main   ons   str   nod   

今天考试考了这题,所以来贡献\([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\n");
            else printf("NIE\n");
        }
    }
    return 0;
}

[POI2015]LOG

标签:else   getc   原来   amp   pac   main   ons   str   nod   

原文地址:https://www.cnblogs.com/owencodeisking/p/9534903.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!