zoukankan      html  css  js  c++  java
  • 色板游戏(线段树)

    色板游戏

    题目背景:
    阿宝上学了,今天老师拿来了一块很长的涂色板。
    题目描述:
    色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格。并从左到右标记为1, 2, … L。现在色板上只有一个颜色,老师告诉阿宝在色板上只能做两件事:1. “C A B C” 指在A到 B 号方格中涂上颜色 C。2. “P A B” 指老师的提问:A到 B号方格中有几种颜色。学校的颜料盒中一共有 T 种颜料。为简便起见,我们把他们标记为 1, 2, … T. 开始时色板上原有的颜色就为1号色。 面对如此复杂的问题,阿宝向你求助,你能帮助他吗?
    输入输出格式:
    输入格式:
    第一行有3个整数 L (1 <= L <= 100000), T (1 <= T <= 30) 和 O (1 <= O <= 100000). 在这里O表示事件数, 接下来 O 行, 每行以 “C A B C” 或 “P A B” 得形式表示所要做的事情(这里 A, B, C 为整数, 可能A> B)
    输出格式:
    对于老师的提问,做出相应的回答。每行一个整数。
    输入输出样例:
    输入样例#1:
    2 2 4
    C 1 1 2
    P 1 2
    C 2 2 2
    P 1 2
    输出样例#1:
    2
    1

    思路:
    线段树
    区间修改就是普通的修改,关键在区间查询,即如何统计出某一区间中有多少种颜色。
    写一个函数:check,如果tree[tree[k].lch].color!=tree[tree[k].rch].color,则把tree[k].color设为-1,意思是这个节点左二子和右儿子的颜色不一样。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=100010;
    int n,m,t,tot;
    bool flag[35];
    struct node
    {
        int l,r;
        int lch,rch;
        int flag;
        int color;
    }tree[maxn*4];
    char c;
    int init()
    {
        int f=1,p=0;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){p=p*10+c-'0';c=getchar();}
        return f*p;
    }
    void build_tree(int ll,int rr)
    {
        int cur=++tot;
        tree[cur].l=ll;
        tree[cur].r=rr;
        if(ll!=rr-1)
        {
            int mid=(ll+rr)>>1;
            tree[cur].lch=tot+1;
            build_tree(ll,mid);
            tree[cur].rch=tot+1;
            build_tree(mid,rr);
            tree[cur].color=1;
        }
        else tree[cur].color=1;
    }
    void update(int k)
    {
        tree[tree[k].lch].color=tree[k].flag;
        tree[tree[k].rch].color=tree[k].flag;
        tree[tree[k].lch].flag=tree[k].flag;
        tree[tree[k].rch].flag=tree[k].flag;
        tree[k].flag=0;
    }
    void check(int k)//检查函数
    {
        if(tree[tree[k].lch].color==tree[tree[k].rch].color)
        tree[k].color=tree[tree[k].lch].color;
        else tree[k].color=-1;
    }
    void change(int k,int l,int r,int p)
    {
        if(l<=tree[k].l&&r>=tree[k].r)
        {
            tree[k].color=p;
            tree[k].flag=p;
            return;
        }
        if(tree[k].flag)
        update(k);
        int mid=(tree[k].l+tree[k].r)>>1;
        if(l<mid) change(tree[k].lch,l,r,p);
        if(r>mid) change(tree[k].rch,l,r,p);
        check(k);
    }
    void find(int k,int l,int r)
    {
        if(l<=tree[k].l&&r>=tree[k].r&&tree[k].color!=-1)//注意判断
        {
            flag[tree[k].color]=1;
            return;
        }
        if(tree[k].flag)
        update(k);
        int mid=(tree[k].l+tree[k].r)>>1;
        if(l<mid) find(tree[k].lch,l,r);
        if(r>mid) find(tree[k].rch,l,r);
    }
    int main()
    {
        int x,y,z;
        n=init();t=init();m=init();
        build_tree(1,n+1);
        for(int i=1;i<=m;i++)
        {
            cin>>c;
            if(c=='C')
            {
                x=init();y=init();z=init();
                if(x>y) swap(x,y);
                change(1,x,y+1,z);
            }
            else
            {
                memset(flag,0,sizeof(flag));
                int ans=0;
                x=init();y=init();
                if(x>y) swap(x,y);
                find(1,x,y+1);
                for(int j=1;j<=t;j++)
                if(flag[j])
                ans++;
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    什么是香港3c专线精品网和3c直连网络服务器
    服务器被攻击后处理办法
    服务器Linux系统安全维护基础知识介绍
    服务器宕机原因分析
    公网,专用,共享独立IP介绍
    服务器内存种类和各自特性
    自主组装服务器行不行
    英语网址大全收藏
    【分享】地产集团公司LOGO设计
    星际争霸2logo在线制作
  • 原文地址:https://www.cnblogs.com/cax1165/p/6070956.html
Copyright © 2011-2022 走看看