zoukankan      html  css  js  c++  java
  • 动态开点线段树(陕西师范18k题)---get new skill

    思想:

      每次开点的时候:左右孩子都开辟新空间

      注意懒惰标记tag: 因为会向下传递

           提前在值中减去懒惰标记,避免重复计算

    链接:https://www.nowcoder.com/acm/contest/121/H
    来源:牛客网

    乐于助人,善于团结,吃苦耐劳,平易近人,尊敬师长,团结同学,心地善良,为人诚实,一心一意,精明能干,个性稳重······的ddjing,为了柯怡着想,非常善良诚恳地向她提出一个很有建设性的建议————她该减肥了!

    柯怡听了之后非常不高兴!她坚定的认为自己是微胖(连233斤都没有怎么能叫胖!)!而微胖才是最受欢迎的!并且做出了一个人神公愤的决定!她居然想要以此为借口欺负ddjing!

    委屈的ddjing生气了!所以ddjing决定对柯怡降下天罚!这把柯怡吓得到处乱跑!

     

    然而柯怡也不能坐以待毙,她知道每次天罚的时候ddjing会在[li,ri]之间劈下xi道闪电,而她当时会站在某个位置,由于她的身躯过于肥胖,她会占据[keyiLi,keyiRi]这段区间(为什么柯怡的体型会不同呢?因为柯怡逃跑的时候可能消耗掉一些脂肪,体型就会减少,而当她跑累的时候她又会去吃吃吃,体型就又会变大);

     

    忙于逃跑的柯怡实在没办法算的过来,因为零食早已塞满了她的大脑,所以她决定求助于你;

    她想知道,在ddjing降下这次天罚之后,她现在所处的位置已经被闪电劈过多少次了?(这方便她去估算下一次逃跑的方向)

     

    ddjing也猜测到了柯怡想预判他的天罚位置,所以他决定对他的天罚情报进行加密;

    聪明的ddjing知道上一次柯怡所处的位置已经被resi-1道闪电劈过了,并且他成功入侵了柯怡与你进行py交易的app,所以他会把数据篡改了;

    幸好聪明的你发现了还原数据的方法;

     

    因为ddjing十分坚持不懈,所以他一共向柯怡提了T次减肥建议;

    每次提完减肥建议的时候,生气的ddjing会降下n次天罚;

    每次天罚的时候,你会收到柯怡发过来的,包括li,ri,xi,keyiLi,keyiRi,其中li,ri,keyiLi,keyiRi都是被ddjing篡改过的(不包括xi),而还原数据的方法是将这些被篡改过的数据按位异或(xor)上(resi-1 %19980105),而你需要告诉柯怡,在ddjing这次天罚降下以后,她所处于的位置已经被闪电劈过多少次了;

    输入描述:

    一共有T(T<=10)组数据,对于每组数据,第一行有一个整数n,代表ddjing降下的天罚次数,接下来会有n(n<=100000)行,每一行有5个整数,分别为li,ri,keyiLi,keyiRi (0<=li,ri,keyiLi,keyiRi<=1000000000,1<=xi<=5000);

    其中,i是从1开始计数的,而res0 =0;

    输出描述:

    对于每次天罚,你需要输出一个整数,代表柯怡在这次天罚之后,她所处于的位置已经被闪电劈了多少次了;

    示例1

    输入

    复制
    1
    4
    1 3 5 2 4
    2 3 1 1 1
    150 250 8 2 4
    1 2 3 4 5

    输出

    复制
    10
    0
    10
    0

    说明

    对于第1次天罚,res0 = 0,l1^(0%19980105)=1,r1^(0%19980105)=3,keyiL1^(0%19980105)=2,keyiR1^(0%19980105)=4,在这次天罚后,柯怡所在的位置中的[2,3]分别被闪电劈过了5次,所以res1=10;

    对于第2次天罚,res1 =10,l2^(10%19980105)=8,r2^(10%19980105)=9,keyiL2^(10%19980105)=11,keyiR2^(10%19980105)= 11,所以res2=0;

    对于第三次天罚柯怡占据了[2,4],[2,3]在第一次天罚中已经被劈过了,所以res3 =10;

    对于第四次天罚,res3=10,l4 ^(10%19980105)=11,r4^(10%19980105)=8,所以ddjing降下天罚的范围是[8,11];

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 struct node {
     5     LL sum;
     6     LL lson;
     7     LL rson;
     8     LL tag;
     9 };
    10 const int N=4e6+7;// 点要开20~40倍
    11 const LL X=1e9;
    12 const LL p=19980105;
    13 node tree[N];
    14 int n,cnt;
    15 void newnode (LL &rt,LL x) {
    16     rt=++cnt;
    17     tree[rt].sum=x;
    18     tree[rt].lson=tree[rt].rson=-1;
    19     tree[rt].tag=0;
    20 }
    21 void pushdown (LL rt,LL l,LL r) {
    22     LL m=(l+r)/2;
    23     if (tree[rt].tag) {
    24         tree[tree[rt].lson].sum+=tree[rt].tag*(m-l+1);
    25         tree[tree[rt].lson].tag+=tree[rt].tag;
    26         tree[tree[rt].rson].sum+=tree[rt].tag*(r-m);
    27         tree[tree[rt].rson].tag+=tree[rt].tag;
    28         tree[rt].tag=0;
    29     }
    30 }
    31 void pushup (LL rt) {
    32     tree[rt].sum=tree[t ree[rt].lson].sum+tree[tree[rt].rson].sum;
    33 }
    34 void update (LL L,LL R,LL x,LL l,LL r,LL rt) {
    35     if (l>R||r<L)  return ;
    36     if (l>=L&&r<=R) {
    37         tree[rt].sum+=(r-l+1)*x;
    38         tree[rt].tag+=x;
    39         return ;
    40     } 
    41     LL m=(l+r)/2; LL k=tree[rt].sum/(r-l+1)-tree[rt].tag;// 提前减去tag
    42     if (tree[rt].lson<0) newnode (tree[rt].lson,k*(m-l+1));
    43     if (tree[rt].rson<0) newnode (tree[rt].rson,k*(r-m));
    44     pushdown(rt,l,r);// 因为这里会自动加上tag
    45     update (L,R,x,l,m,tree[rt].lson);
    46     update (L,R,x,m+1,r,tree[rt].rson);
    47     pushup(rt);
    48     return ;
    49 }
    50 LL query (LL L,LL R,LL l,LL r,LL rt) {
    51     if (l>R||r<L)  return 0;
    52     if (l>=L&&r<=R)  return tree[rt].sum;
    53     LL m=(l+r)/2; LL k=tree[rt].sum/(r-l+1)-tree[rt].tag;
    54     if (tree[rt].lson<0) newnode (tree[rt].lson,k*(m-l+1));
    55     if (tree[rt].rson<0) newnode (tree[rt].rson,k*(r-m));
    56     pushdown(rt,l,r);
    57     return query (L,R,l,m,tree[rt].lson)+query (L,R,m+1,r,tree[rt].rson);
    58 }
    59 int main ()
    60 {
    61     int T; scanf ("%d",&T);
    62     while (T--) {
    63         cnt=0;
    64         LL res=0,rt=++cnt;
    65         tree[rt].sum=tree[rt].tag=0;
    66         tree[rt].lson=tree[rt].rson=-1;
    67         scanf ("%d",&n);
    68         for (int i=1;i<=n;i++) {
    69             LL l,r,x,kl,kr;
    70             scanf ("%lld %lld %lld %lld %lld",&l,&r,&x,&kl,&kr);
    71             l=l^res; r=r^res; kl=kl^res; kr=kr^res;
    72             if (l>r) swap(l,r); if (kl>kr) swap(kl,kr);
    73             update (l,r,x,0,X,rt);
    74             res=query (kl,kr,0,X,rt);
    75             printf("%lld
    ",res);
    76             res%=p;
    77         }
    78     }
    79     return 0;
    80 }
    抓住青春的尾巴。。。
  • 相关阅读:
    面试笔试题
    类型转换
    c++11之智能指针
    c++预处理命令
    java的javac不能正常运行
    状态模式
    观察者模式Observer
    带图形界面的虚拟机安装+Hadoop
    测试工具的使用:JUnit、PICT、AllPairs
    Test_1 一元二次方程用例测试以及测试用例
  • 原文地址:https://www.cnblogs.com/xidian-mao/p/9424922.html
Copyright © 2011-2022 走看看