Monkeying Around 线段树+树状数组

来源:互联网 发布:yum 不支持python 2.7 编辑:程序博客网 时间:2024/06/05 23:47

题目大意,给定若干(Li, Ri, Ki)表示Li到Ri的人都得到一个标号为ki的球,依次进行。n个人每个人有一个状态0或者1,如果在这次操作前已经有过ki这种球了,那么状态会变成0,否则变成1.初始的时候都是0.求m次操作后有多少个0.
题解:一开始想错了,后来发现是个傻逼提。唯一需要考虑的性质是,每个人的最终状态 基 本 上 由最后一次覆盖到他的操作的ki决定。(题面是经过一点点转化的,所以现在看起来很显然)。
如果第i个人没有被任何区间覆盖,那么最后显然是0.
假设第i个人最后拿到的球的编号是ai,如果他拿了两次及以上的ai,那么状态是0,否则是1.
因此首先用线段树处理出每个人最后一个得到的球的编号。然后枚举球的编号x,把ki=x的区间+1,检查那些最后得到x的人时候只被覆盖一次即可,这部分显然树状数组一下即可。如果代码实现不好需要特判一下没有拿到球的人。注意多组数据。

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#define N 100010#define lb(x) (x&-x)#define solve(s,t,v) update(s,v),update(t+1,-v)using namespace std;struct segment{    int l,r,v;    segment *ch[2];}*rt;int n;struct node{    int L,R;    node(int l,int r)    {        L=l,R=r;    }    inline node operator=(const node &n)    {        L=n.L,R=n.R;return *this;    }};vector<int> v[N];vector<node> q[N];int build(segment* &rt,int l,int r){    rt=new segment;rt->l=l,rt->r=r,rt->v=0;    if(l==r) return 0;int mid=(l+r)>>1;    build(rt->ch[0],l,mid),build(rt->ch[1],mid+1,r);    return 0;}int Clear(segment* &rt){    int l=rt->l,r=rt->r;rt->v=0;if(l==r) return 0;    return Clear(rt->ch[0]),Clear(rt->ch[1]);}inline int push_down(segment* &rt){    rt->ch[0]->v=rt->v;    rt->ch[1]->v=rt->v;    return rt->v=0;}int update(segment* &rt,int s,int t,int v){    int l=rt->l,r=rt->r,mid=(l+r)>>1;    if(s<=l&&r<=t) return rt->v=v;    if(rt->v) push_down(rt);    if(s<=mid) update(rt->ch[0],s,t,v);    if(mid<t) update(rt->ch[1],s,t,v);    return 0;}int PUSH(segment* &rt){    int l=rt->l,r=rt->r;    if(l==r) return (l<=n?v[rt->v].push_back(l),0:0),0;    if(rt->v) push_down(rt);    PUSH(rt->ch[0]),PUSH(rt->ch[1]);    return 0;}int c[N];inline void update(int x,int v){    for(;x<=n;x+=lb(x)) c[x]+=v;}inline int query(int x){    int ans=0;    for(;x;x-=lb(x)) ans+=c[x];    return ans;}int main(){    int T;scanf("%d",&T);build(rt,1,N);    while(T--)    {        int m;scanf("%d%d",&n,&m);        Clear(rt);int maxl=0;        for(int i=0;i<N;i++) v[i].clear(),q[i].clear();        for(int i=1,x,l,k;i<=m;i++)        {            scanf("%d%d%d",&x,&l,&k),maxl=max(maxl,l);            update(rt,max(1,x-k),min(n,x+k),l);            q[l].push_back(node(max(1,x-k),min(n,x+k)));        }        PUSH(rt);int ans=0;        for(int i=1;i<=maxl;i++)        {            for(int j=0;j<q[i].size();j++)                solve(q[i][j].L,q[i][j].R,1);            for(int j=0;j<v[i].size();j++)                if(query(v[i][j])==1) ans++;            for(int j=0;j<q[i].size();j++)                solve(q[i][j].L,q[i][j].R,-1);        }        printf("%d\n",n-ans+v[0].size());    }    return 0;}
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 支气管发炎严重吗 支气管炎吃什么好 支气管炎一直咳嗽怎么办 支气管炎引起的咳嗽 支气管炎老咳嗽怎么办 支气管炎咳嗽症状 支气管炎和气管炎 如何判断自己是不是气管炎 气管镜的危害 气管镜检查多少钱 做气管镜有危险吗 做气管镜对人有伤害吗 气管镜检查的目的 喉镜下的气管食管图片 气管镜的作用 气管镜怎么做 气管镜检查什么 做气管镜难受吗 气定神闲宏 气组词 气的组词 气组词有哪些 气字组词 气字开头组词 气组词接龙 气的组词有那些 气组词两个字 气的组词是什么 气怎么组词 气的组词大全 气缸的力怎么计算 双向气缸 shako气缸 sda气缸尺寸 180度旋转气缸 气动阀门气缸 气缸套 气缸垫冲了算大修吗 气缸防护套 气缸套有哪两种 气缸油