• [HNOI/AHOI2018]转盘


    题目描述

    一次小G和小H准备去聚餐,但是由于太麻烦了于是题面简化如下:

    一个转盘上有摆成一圈的 nn 个物品(编号1~ nn ),其中的 ii 个物品会在 T_iTi 时刻出现。

    在0时刻时,小G可以任选 nn 个物品中的一个,我们将其编号为 s_0s0 。并且如果 ii 时刻选择了物品 s_isi ,那么 i+1i+1 时刻可以继续选择当前物品或选择下一个物品。当 s_isi 为 nn 时,下一个物品为物品 11 ,否则为物品 s_{i}+1si+1 。在每一时刻(包括0时刻),如果小G选择的物品已经出现了,那么小G将会标记它。小H想知道,在物品选择的最优策略下,小G什么时候能标记所有物品?

    但麻烦的是,物品的出现时间会不时修改。我们将其描述为 mm 次修改,每次修改将改变其中一个物品的出现时间。每次修改后,你也需求出当前局面的答案。对于其中部分测试点,小H还追加了强制在线的要求。

    输入输出格式

    输入格式:

    第一行三个非负整数 nn 、 mm 、 pp ,代表一共有 nn 个物品, mm 次修改。 pp 只有0或1两种取值,强制在线时 pp 为1,否则 pp 为0.

    接下来一行,有 nn 个非负整数,第 ii 个数 T_iTi 代表物品 ii 的出现时间。

    接下来 mm 行,每行两个非负整数 xx 、 yy ,代表一次修改及询问。修改方式如下:

    (1)如果 p=0p=0 ,则表示物品 xx 的出现时间 T_xTx 修改为 yy 。

    (2)如果 p=1p=1 ,在先将 xx 和 yy 分别异或 LastAnsLastAns ,得到 x'x′ 和 y'y′ ,然后将物品 x'x′ 的出现时间 T_{x'}Tx 修改为 y'y′。其中的 LastAnsLastAns 是前一个询问的结果;特别的,第一次修改时 LastAnsLastAns 为初始局面的答案。

    保证输入合法。

    输出格式:

    第一行一个整数,代表初始局面的答案。

    接下来 mm 行每行一个整数,分别代表每次修改后的答案。

    输入输出样例

    输入样例#1: 复制
    5 3 0
    1 2 3 4 5
    3 5
    5 0
    1 4
    输出样例#1: 复制
    5
    7
    6
    7

    说明

    【数据范围】

    3≤n≤10^5,0≤m≤10^5,0≤T_i/T_x≤10^53n105,0m105,0Ti/Tx105 。

    传送门

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 using namespace std;
     7 int val[800001],Max[800001],a[800001],n,m,p,t[800001],ans;
     8 int query(int rt,int l,int r,int Mx)
     9 {
    10   if (l==r)
    11     {
    12       return l+max(Mx,Max[rt]);
    13     }
    14   int mid=(l+r)/2;
    15   if (Mx<=Max[rt<<1|1])
    16     return min(val[rt],query(rt<<1|1,mid+1,r,Mx));
    17   else return min(mid+Mx+1,query(rt<<1,l,mid,Mx));
    18 }
    19 void pushup(int rt,int l,int r)
    20 {
    21   int mid=(l+r)/2;
    22   val[rt]=query(rt<<1,l,mid,Max[rt<<1|1]);
    23   Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
    24 }
    25 void update(int rt,int l,int r,int x)
    26 {
    27   if (l==r)
    28     {
    29       Max[rt]=a[l];
    30       val[rt]=a[l]+l;
    31       return;
    32     }
    33   int mid=(l+r)/2;
    34   if (x<=mid) update(rt<<1,l,mid,x);
    35   else update(rt<<1|1,mid+1,r,x);
    36   pushup(rt,l,r);
    37 }
    38 void build(int rt,int l,int r)
    39 {
    40   if (l==r)
    41     {
    42       Max[rt]=a[l];
    43       val[rt]=a[l]+l;
    44       return;
    45     }
    46   int mid=(l+r)/2;
    47   build(rt<<1,l,mid);
    48   build(rt<<1|1,mid+1,r);
    49   pushup(rt,l,r);
    50 }
    51 int main()
    52 {int i,x,y;
    53   cin>>n>>m>>p;
    54   for (i=1;i<=n;i++)
    55     {
    56       scanf("%d",&t[i]);
    57       a[i]=t[i]-i;
    58       a[n+i]=t[i]-n-i;
    59     }
    60   build(1,1,n<<1);
    61   ans=val[1]+n-1;
    62   printf("%d
    ",ans);
    63   for (i=1;i<=m;i++)
    64     {
    65       scanf("%d%d",&x,&y);
    66       x^=ans*p;y^=ans*p;
    67       t[x]=y;
    68       a[x]=t[x]-x;
    69       a[n+x]=t[x]-n-x;
    70       update(1,1,n<<1,x);
    71       update(1,1,n<<1,n+x);
    72       ans=val[1]+n-1;
    73       printf("%d
    ",ans);
    74     }
    75 }
  • 相关阅读:
    Objective-c Category(类别)
    协议(porotocol)
    类的通用格式
    objective-c 强大的布尔类型
    C 语言函数指针
    c while 循环
    jQuery的deferred对象详解
    exploring the http Object
    div+css定位position详解
    如何给变量取个简短且无歧义的名字
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8964166.html
Copyright © 2020-2023  润新知