zoukankan      html  css  js  c++  java
  • CodeForces

    题目

    晚上有n个亮着的灯泡,标号从1到n。

    现在存在2种操作,如下:

    • 操作1,关掉标号 [l,r] 区间的灯
    • 操作2,打开标号 [l,r] 区间的灯

    下面有q次询问,每次询问执行其中一种操作,询问格式,l,r,k,k为执行操作种类。对于每次询问回答当前开着的灯的数量。

    Input

    单组输入,第一行包含一个整数n,第二行一个整数q(1≤n≤10^9,1≤q≤3·10^5)

    接下来q行每行3个整数表示询问,l,r,k(1 ≤ l ≤ r ≤ n, 1 ≤ k ≤ 2).

    Output

    对于每次询问回答一个整数占一行表示答案。

    Example

    Input
    4
    6
    1 2 1
    3 4 1
    2 3 2
    1 3 2
    2 4 1
    1 4 2
    Output
    2
    0
    2
    3
    1
    4

    题解:

    因为线段树要开4倍空间。然而面对庞大的数据我们开maxn<<2的空间是肯定开不下的。

    这时候就要用到动态开点线段树来节省空间了。( 或者离散化 )

    动态开点也就是当用到那个节点的时候才给它分配空间,否则就不分配,就比如像这一道题n的大小是1e9,那么静态开点肯定炸空间了,,,但是你发现他询问的区间也就3e5个,可见用到的区间还是少数,所以每当用到一个区间我们再给他分配空间

    代码:

     1 /*
     2 动态开点线段树
     3 */
     4 #include<stdio.h>
     5 #include<string.h>
     6 #include<iostream>
     7 #include<algorithm>
     8 #include<queue>
     9 #include<vector>
    10 using namespace std;
    11 const int maxn=3e5+10;
    12 const int INF=0x3f3f3f3f;
    13 typedef long long ll;
    14 struct Node
    15 {
    16     int l,r,sum,lazy;
    17     Node()
    18     {
    19         l=0,r=0,sum=0,lazy=0;
    20     }
    21 } node[maxn*50];
    22 int cnt=1;  //开点的数量
    23 void pushdown(int l,int r,int k) //k是父节点在数组中的序号
    24 {
    25     int mid=(l+r)>>1;
    26     if(l!=r)
    27     {
    28         if(!node[k].l) node[k].l=++cnt;
    29         if(!node[k].r) node[k].r=++cnt;
    30 
    31         if(node[k].lazy==2)
    32         {
    33             node[node[k].l].sum=node[node[k].r].sum=0;
    34         }
    35         else
    36         {
    37             node[node[k].l].sum=mid-l+1;
    38             node[node[k].r].sum=r-mid;
    39         }
    40         node[node[k].l].lazy=node[k].lazy;
    41         node[node[k].r].lazy=node[k].lazy;
    42     }
    43     node[k].lazy=0;
    44 }
    45 //往线段树里面插入一个区间[L,R]
    46 void Insert(int l,int r,int &k,int L,int R,int p)
    47 {
    48     if(!k) k=++cnt;  //这个k也就相当于我们要对node[k]这个节点进行操作
    49     //node[1]是根节点,因为我们这是动态开点,所以没有开点的节点都是初始值0
    50     if(l>=L && r<=R)  //如果满足这个条件也就不需要pushdown,因为我们不需要下面节点就可以得到[l,r]区间内的答案
    51     {
    52         if(p==2) node[k].sum=0;
    53         else node[k].sum=r-l+1;
    54         node[k].lazy=p;
    55         return;
    56     }
    57     //如果不满足上面那个判断,那么我们就要递归进入k的左右子节点,这个时候,你要保证左右子点都已经被修改好了
    58     //即,懒惰标记lazy是0
    59     if(node[k].lazy) pushdown(l,r,k);
    60     int mid=(l+r)>>1;
    61     if (mid>=L) Insert(l,mid,node[k].l,L,R,p);
    62     if (mid<R) Insert(mid+1,r,node[k].r,L,R,p);
    63     node[k].sum=node[node[k].l].sum+node[node[k].r].sum;
    64 }
    65 int main()
    66 {
    67     //printf("%d %d
    ",node[1].l,node[1].r);
    68     int n,q;
    69     scanf("%d %d",&n,&q);
    70     int k=1;
    71     for (int i=1; i<=q; i++)
    72     {
    73         int l,r,p;
    74         scanf("%d %d %d",&l,&r,&p);
    75         Insert(1,n,k,l,r,p);
    76         printf("%d
    ",n-node[1].sum);
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    Unable To Open Database After ASM Upgrade From Release 11.1 To Release 11.2
    11g Understanding Automatic Diagnostic Repository.
    How to perform Rolling UpgradeDowngrade in 11g ASM
    Oracle 11.2.0.2 Patch 说明
    Pattern Matching Metacharacters For asm_diskstring
    Steps To MigrateMove a Database From NonASM to ASM And ViceVersa
    Upgrading ASM instance from Oracle 10.1 to Oracle 10.2. (Single Instance)
    OCSSD.BIN Process is Running in a NonRAC Environment
    Steps To MigrateMove a Database From NonASM to ASM And ViceVersa
    On RAC, expdp Removes the Service Name [ID 1269319.1]
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12621431.html
Copyright © 2011-2022 走看看