hdu5023 ( 广州网络赛 ) 线段树

题意是给你n个连续的点(1-n) m次操作  开始每个点都为2

两种操作

1:把一段区间的点变为c

2:询问区间有多少种点

很明显的线段树      对每个节点

flash表示该节点是否全为一样的数  若是  则flash=这个数否则  flash=-1;

数组color记录该节点输得状态    1表示有0表示没有(我开成字符型  之前为int超类存了   真是无语)

然后  有更新和查询操作

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) ((x<<1)|1)

struct node
{
    char color[31];
    int flash;
}num[3* 1000000];
int leap[31];
int change(int mark,int k)
{
    for(int i=1;i<=30;i++)
    {
        num[mark].color[i]=‘0‘;
    }
    num[mark].color[k]=‘1‘;
    return 0;
}
int deal(int L,int R,int mark)
{
    num[mark].flash=2;
    change(mark,2);
    int mid=(L+R)/2;
    if(L==R) return 0;
    deal(L,mid,LL(mark));
    deal(mid+1,R,RR(mark));
    return 0;
}//注意题目说开始时每个点都是2
int update(int L,int R,int left,int right,int mark,int k)
{
    int mid=(L+R)/2;
    if(num[mark].flash==k) return 0;//一个小优化
    if(L==left&&R==right)
    {
        num[mark].flash=k;
        change(mark,k);
        return 0;
    }
    if(num[mark].flash>0)
    {
        num[LL(mark)].flash=num[RR(mark)].flash=num[mark].flash;
        change(LL(mark),num[mark].flash);
        change(RR(mark),num[mark].flash);
    }
    if(right<=mid)
    {
        update(L,mid,left,right,LL(mark),k);
    }
    else if(left>mid)
    {
        update(mid+1,R,left,right,RR(mark),k);
    }
    else
    {
        update(L,mid,left,mid,LL(mark),k);
        update(mid+1,R,mid+1,right,RR(mark),k);
    }
    for(int i=1;i<=30;i++)
    {
        if(num[LL(mark)].color[i]==‘1‘||num[RR(mark)].color[i]==‘1‘)
        {
            num[mark].color[i]=‘1‘;
        }
        else num[mark].color[i]=‘0‘;
    }
    if(num[LL(mark)].flash==num[RR(mark)].flash&&num[LL(mark)].flash>0) num[mark].flash=num[LL(mark)].flash;
    else num[mark].flash=-1;
    return 0;
}
int find(int L,int R,int left,int right,int mark)
{
    int mid=(L+R)/2;
    if(num[mark].flash!=-1)
    {
        leap[num[mark].flash]=1;
        return 0;
    }
    if(L==left&&R==right)
    {
        for(int i=1;i<=30;i++)
        {
            if(num[mark].color[i]==‘1‘) leap[i]=1;
        }
    }
    if(right<=mid)
    {
        find(L,mid,left,right,LL(mark));
    }
    else if(left>mid)
    {
        find(mid+1,R,left,right,RR(mark));
    }
    else
    {
        find(L,mid,left,mid,LL(mark));
        find(mid+1,R,mid+1,right,RR(mark));
    }
    return 0;
}
int main()
{
    int n,m,i,j,a,b,c;
    char str[5];
    while(~scanf("%d%d",&n,&m),n+m)
    {
        deal(1,n,1);
        for(j=1;j<=m;j++)
        {
            scanf("%s",str);
            if(str[0]==‘P‘)
            {
                scanf("%d%d%d",&a,&b,&c);
                update(1,n,a,b,1,c);
            }
            else
            {
                scanf("%d%d",&a,&b);
                memset(leap,0,sizeof(leap));
                find(1,n,a,b,1);
                int d=1;
                for(i=1;i<=30;i++)
                {
                    if(leap[i])
                    {
                        if(d!=1) printf(" ");
                        printf("%d",i);
                        d++;
                    }
                }
                printf("\n");
            }
        }
    }
    return 0;
}
时间: 2024-10-29 03:20:34

hdu5023 ( 广州网络赛 ) 线段树的相关文章

HDU 5023 (2014广州网络赛 线段树)

解题思路: 有两种操作,第一种是将区间 a 到 b 染成颜色 c ,第二种是询问区间 a  到 b 内的颜色,按照顺序输出. 注意到颜色只有三十种,因此我们可以用二进制数表示颜色,通过位运算来操作. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <vector> #include

HDU6447 YJJ&#39;s Salesman-2018CCPC网络赛-线段树求区间最值+离散化+dp

目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门 ?原题目描述在最下面. ?1e5个点,问从(0,0)走到(1e9,1e9)的最大收益. ?当你从(u-1,v-1)走到(u,v)时,你可以获得点(u,v)的权值. Solution: ?十分详细了. ?直接线段树区间最值.当然也可以树状数组,不能st表. ?\(dp[i] = max(query\_max(0,dp[i]-1,1)+val[i] ,

hdu 4027 2011上海赛区网络赛 线段树 成段平方根 ***

不能直接使用成段增减的那种,因为一段和的平方根不等于平方根的和,直接记录是否为1,是1就不需要更新了 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #de

hdu 5023 A Corrupt Mayor&#39;s Performance Art(广州网络赛)

A Corrupt Mayor's Performance Art                                                                  Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submission(s): 341    Accepted Submission(s): 150 Problem D

HDU 5024 Wang Xifeng&#39;s Little Plot(2014广州网络赛1003)

写了1h的DFS,简直被自己的代码吓哭了..不过起码还是思路清晰,QUQ~ 说一下题意吧: 题意是求一条最长路,最多能经过一次转弯,并且其角度只能为90度. 拿第一个样例来说:(0,1)->(1,2)->[转弯](2,1) ,所以答案是3. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5024 代码如下: #include<iostream> #include<cstdio> #include<cstring>

HDU 5024 Wang Xifeng&#39;s Little Plot(广州网络赛C题)

HDU 5024 Wang Xifeng's Little Plot 题目链接 思路:先利用记忆化搜索预处理出每个结点对应8个方向最远能走多远,然后枚举拐点记录最大值即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int d[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1,

HDU 5024 (广州网络赛) Wang Xifeng&#39;s Little Plot 记忆化搜索+枚举

Problem Description <Dream of the Red Chamber>(also <The Story of the Stone>) is one of the Four Great Classical Novels of Chinese literature, and it is commonly regarded as the best one. This novel was created in Qing Dynasty, by Cao Xueqin.

query 2019徐州网络赛(树状数组)

query \[ Time Limit: 2000 ms \quad Memory Limit: 262144 kB \] 题意 补题才发现比赛的时候读了一个假题意.... 给出长度为 \(n\) 的排列,在给出 \(m\) 次询问,每次询问有一对 \(l.r\),问满足 \(min(ai, aj) = gcd(ai, aj)\) 的 \(pair(i, j)\) 对数. 思路 考虑离线做 先把每个数出现的位置记录下来,然后预处理出所有的 \(pair\). 对于一个数字 \(x\),其满足条件

HDU-5025 2014广州网络赛 Saving Tang Monk 状压+BFS

给出一个N*N的矩阵,开启牢门需要收集齐m种钥匙,且必须收集了前i-1种钥匙才能收集第i种钥匙,最终收集齐了回到关押唐僧的房间拯救唐僧,经过一个'S'的房间时需要额外耗时把蛇打死,蛇最多5条,所以状压一下用优先队列BFS求最小时间即可. #include <iostream> #include <cstdio> #include <cmath> #include <queue> #include <vector> #include <cst