色板游戏(洛谷 1558)

题目背景

阿宝上学了,今天老师拿来了一块很长的涂色板。

题目描述

色板长度为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

/*
  可以选择状态压缩,把30种颜色装换成二进制,这样单点修改就行了;
  也可以用vis数组维护,这样要区间修改,每次查询更新vis数组,lz用第二种方法做的。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define lson l,mid,now*2
#define rson mid+1,r,now*2+1
#define M 100010
#define N 32
using namespace std;
int sum[M*4],tag[M*4],vis[N],n,t,m;
void push_up(int now)
{
    if(sum[now*2]==sum[now*2+1])sum[now]=sum[now*2];
    else sum[now]=-1;
}
void push_down(int now)
{
    if(!tag[now])return;
    tag[now*2]=tag[now];
    sum[now*2]=tag[now];
    tag[now*2+1]=tag[now];
    sum[now*2+1]=tag[now];
    tag[now]=0;
}
void change(int x,int y,int v,int l,int r,int now)
{
    if(l>=x&&r<=y)
    {
        sum[now]=tag[now]=v;
        return;
    }
    push_down(now);
    int mid=(l+r)/2;
    if(x<=mid)change(x,y,v,lson);
    if(y>mid)change(x,y,v,rson);
    push_up(now);
}
void query(int x,int y,int l,int r,int now)
{
    if(l>=x&&r<=y&&sum[now]!=-1)
    {
        vis[sum[now]]=1;
        return;
    }
    push_down(now);
    int mid=(l+r)/2;
    if(x<=mid)query(x,y,lson);
    if(y>mid)query(x,y,rson);
}
int main()
{
    scanf("%d%d%d",&n,&t,&m);
    for(int i=1;i<=n;i++)change(i,i,1,1,n,1);
    for(int i=1;i<=m;i++)
    {
        char c;cin>>c;
        if(c==‘C‘)
        {
            int x,y,v;
            scanf("%d%d%d",&x,&y,&v);
            if(x>y)swap(x,y);
            change(x,y,v,1,n,1);
        }
        else
        {
            memset(vis,0,sizeof(vis));
            int x,y,tot=0;
            scanf("%d%d",&x,&y);
            if(x>y)swap(x,y);
            query(x,y,1,n,1);
            for(int i=1;i<=t;i++)
              if(vis[i])tot++;
            printf("%d\n",tot);
        }
    }
    return 0;
} 

时间: 2024-10-09 21:54:11

色板游戏(洛谷 1558)的相关文章

AC日记——色板游戏 洛谷 P1558

色板游戏 思路: sb题: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 struct TreeNodeType { int l,r,dis,mid,flag; }; struct TreeNodeType tree[maxn<<2]; int n,m,T,bit[31]; inline void in(int &now) { char Cget=getchar();now=0;

洛谷1558 色板游戏 线段树

我先立个Flag 我,这几天,要过1W道线段树题. 题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, ... L.现在色板上只有一个颜色,老师告诉阿宝在色板上只能做两件事:1. "C A B C" 指在A到 B 号方格中涂上颜色 C.2. "P A B" 指老师的提问:A到 B号方格中有几种颜色.学校的颜料盒中一共有 T 种颜料.为简便起见,我

矩阵取数游戏洛谷p1005

题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值*2^i,其中i表示第i次取数(从1开始编号): 4.游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分. 输入输

AC日记——国王游戏 洛谷 P1080

国王游戏 思路: 贪心+高精: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 struct DataType { int a,b,key; bool operator<(const DataType pos)const { return key<pos.key; } }; struct DataType ai[maxn]; struct BintType { int len; char ch[

AC日记——欧几里得的游戏 洛谷 P1290

题目描述 欧几里德的两个后代Stan和Ollie正在玩一种数字游戏,这个游戏是他们的祖先欧几里德发明的.给定两个正整数M和N,从Stan开始,从其中较大的一个数,减去较小的数的正整数倍,当然,得到的数不能小于0.然后是Ollie,对刚才得到的数,和M,N中较小的那个数,再进行同样的操作……直到一个人得到了0,他就取得了胜利.下面是他们用(25,7)两个数游戏的过程: Start:25 7 Stan:11 7 Ollie:4 7 Stan:4 3 Ollie:1 3 Stan:1 0 Stan赢得

AC日记——矩阵取数游戏 洛谷 P1005

矩阵取数游戏 思路: dp+高精: 代码: #include <bits/stdc++.h> using namespace std; #define ll long long struct Int { int len; char ai[300]; Int() { len=1,ai[0]=0; } void Count(int pos) { len++; if(pos/10) Count(pos/10); } void operator=(int pos_) { int pos=pos_; l

取石子游戏(洛谷_2252)

我随机跳题,跳到了这题,乍一看,不就博弈论吗,题目明明白白的告诉了我们. 诶.........丧啊...不会....... 万般无奈,看了一下题解,是一个叫做威佐夫博弈的东西. 然后百度一下,盯着半天,终于会了,你们也可以百度哦.百度写得足够详细了. #include<iostream> #include<cstdio> #include<cmath> using namespace std; int main() { int a,b;scanf("%d%d&

洛谷P1080 国王游戏 高精度 贪心 数学推公式

洛谷P1080 国王游戏        数学推公式      高精度    贪心 然而这并不是我打出来的,抄题解... 将左手与右手的乘积从小到大排序,然后计算求最大值即可.(需要高精度) 证明: 1)知道,如果相邻的两个人交换位置,只会影响到这两个人的值,不会影响他人 2)假设相邻的两个人i, i + 1.设A[i] B[i] <= A[i + 1] B[i + 1],i之前所有人的左手乘积为S. 则,ans1 = max{S / B[i], S * A[i] / B[i + 1]} 若交换

洛谷 P1005 矩阵取数游戏

题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值*2^i,其中i表示第i次取数(从1开始编号): 4.游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分. 输入输