zoukankan      html  css  js  c++  java
  • wows

    【问题描述】
    山山最近在玩一款游戏叫战舰世界(steam 游戏太少了),他被大舰巨炮的魅力折服,于
    是山山开了一局游戏,这次发现目标是一艘战列舰新墨西哥级,舰桥很高,原本应该打在目
    标身后的圆形水域内的炮弹,都打在了舰桥上,于是落点变成了一条直线。
    因为新墨西哥中间高两边低,所以按概率算,炮弹命中数中间多,两边少,并且中央区
    域容易穿透出现高伤害,所以 山山向中间发射的炮弹比两边多,因为他有强迫症,所以一
    个位置炮弹发射数相对于上一个位置的数目的变化量为 ki(整体大概构成一个山峰状),新墨
    西哥操纵者因为 OI 的时候玩游戏,脑袋被教练按键盘了,所以站着不动,导致山山能够百
    发百中,求数轮齐射后,在一段区域的命中数为阶梯增长的长度 (阶梯增长为 A+0K,
    A+1K· · ·K 随意取,单调增)
    (为了便于统计伤害,我们把新墨西哥分成 n 段,同时也
    便于瞄准。
    新墨西哥被教练抓着脑袋摁键盘了,我就不信我也 gbhghuyjhhfdhsfdhndxf......
    【输入格式】
    输入文件名为 wows.in。
    第一行 n m, 表示新墨西哥被分成 n 段, 山山开炮数和询问命中次数的总数,
    第二行以后每行开头一个 f,0 表示开炮,1 表示询问
    如果开炮 后面还有 5 个参数 l,r,a,k,p
    表示 山山向 l 到 r 段开炮,l 段开了 a 炮,以后 l + 1 到 p 段分别开 a+k,a+k+k,
    a+k+k+k···炮, p+1 到 r 段开 a+(p-l-1)k、a+(p-l-2)k···炮
    如果询问 后面有 l,r 表示询问区域(保证任意相邻区段数据之差在任何时候在 int 内)
    【输出格式】
    输出文件名为 wows.out。
    对于每个询问输出一个数,表示符合要求的最大长度,后跟一个回车
    【样例输入与输出】

    5 3

    0 1 5 2 2 3

    0 4 5 4 4 5

    1 1 5

    输出

    5

    题目大意是每一次给一个区间加上两段等差数列

    在线询问l~r之间的最长等差数列

    这道题最坑的是题意描述,划掉的递增指的是k的系数

    只要等差就行

    于是先差分一次,c[i]=a[i+1]-a[i]那么对于加上a,a+k,a+2k,a+3k,a+2k,a+k这个序列

    差分后等价于a k k k -k -k -a-k

    也就是:c[l-1]+=a,c[l~p-1]+=k,c[p~r-1]-=k,c[r]=-a-(2*p-l-r)*k

    差分后,询问就变成了求差分数组中最长的一段值相同的连续区间长度+1

    这个可以用线段树维护

    对于每个点,维护以下变量:

    ls,rs:线段最左边/右边连续相同的长度

    lp,rp:线段最左边/右边连续相同的数字

    s:当前线段最长连续相等区间

    延迟标记另用一个数组,因为延迟标记不参与合并操作

    合并左右节点的信息:

    首先:c[rt].ls=c[rt*2].ls,c[rt].rs=c[rt*2+1].rs

    c[rt].lp=c[rt*2].lp,c[rt].rp=c[rt*2+1].rp

    c[rt].s=max(c[rt*2].s,c[rt*2+1].s)

    当c[rt*2]全为一个数且c[rt*2].rp与c[rt*2+1].lp相同,那么显然右边区间ls都可以作为新区间的ls

    rs的处理同理

    接下来考虑两个区间对s的影响

    如果c[rt*2].rp==c[rt*2+1].lp那么显然这一段可以作为一段新的连续相同序列

    c[rt].s=max(c[rt].s,c[rt*2].rs+c[rt*2+1].ls)

    其实还可以再差分一次,这样就只涉及单点修改,并询问最长的连续0的数量+2

    拿上面举例

    一次差分后:a k k k -k -k -a-k

    二次差分后:a k-a 0 0 -2k,0,-a,a+k

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 struct Node {
      7     int ls,rs;
      8     int lp,rp;
      9     int s,l,r;
     10 } c[400005];
     11 int n,m,lazy[400005];
     12 Node merge(Node L,Node R) {
     13     Node C;
     14     int mid=L.r;
     15     C.l=L.l;
     16     C.r=R.r;
     17     C.ls=L.ls;
     18     C.rs=R.rs;
     19     C.lp=L.lp;
     20     C.rp=R.rp;
     21     if (L.rs==mid-L.l+1&&L.rp==R.lp)
     22         C.ls+=R.ls;
     23     if (R.ls==R.r-mid&&R.lp==L.rp)
     24         C.rs+=L.rs;
     25     C.s=max(L.s,R.s);
     26     if (L.rp==R.lp)
     27         C.s=max(C.s,L.rs+R.ls);
     28     return C;
     29 }
     30 void build(int rt,int l,int r) {
     31     if (l>r) return;
     32     if (l==r) {
     33         c[rt].l=c[rt].r=l;
     34         c[rt].ls=c[rt].rs=1;
     35         c[rt].lp=c[rt].rp=0;
     36         c[rt].s=1;
     37         return;
     38     }
     39     int mid=(l+r)/2;
     40     build(rt*2,l,mid);
     41     build(rt*2+1,mid+1,r);
     42     c[rt]=merge(c[rt*2],c[rt*2+1]);
     43 }
     44 void pushdown(int rt) {
     45     if (lazy[rt]) {
     46         c[rt*2].lp+=lazy[rt];
     47         c[rt*2].rp+=lazy[rt];
     48         c[rt*2+1].lp+=lazy[rt];
     49         c[rt*2+1].rp+=lazy[rt];
     50         lazy[rt*2]+=lazy[rt];
     51         lazy[rt*2+1]+=lazy[rt];
     52         lazy[rt]=0;
     53     }
     54 }
     55 void add(int rt,int l,int r,int L,int R,int d) {
     56     if (l>r) return;
     57     if (l==L&&r==R) {
     58         c[rt].lp+=d;
     59         c[rt].rp+=d;
     60         lazy[rt]+=d;
     61         return;
     62     }
     63     int mid=(l+r)/2;
     64     pushdown(rt);
     65     if (L>mid)
     66         add(rt*2+1,mid+1,r,L,R,d);
     67     else if (R<=mid)
     68         add(rt*2,l,mid,L,R,d);
     69     else {
     70         add(rt*2,l,mid,L,mid,d);
     71         add(rt*2+1,mid+1,r,mid+1,R,d);
     72     }
     73     c[rt]=merge(c[rt*2],c[rt*2+1]);
     74 }
     75 Node query(int rt,int l,int r,int L,int R) {
     76 
     77     if (l==L&&r==R) {
     78         return c[rt];
     79     }
     80     int mid=(l+r)/2;
     81     pushdown(rt);
     82     c[rt]=merge(c[rt*2],c[rt*2+1]);
     83     if (L>mid)
     84         return query(rt*2+1,mid+1,r,L,R);
     85     else if (R<=mid)
     86         return query(rt*2,l,mid,L,R);
     87     else {
     88         Node cl=query(rt*2,l,mid,L,mid);
     89         Node cr=query(rt*2+1,mid+1,r,mid+1,R);
     90         return merge(cl,cr);
     91     }
     92 }
     93 int main() {
     94     int l,r,a,k,p,i,f;
     95     freopen("wows.in","r",stdin);
     96     freopen("wows.out","w",stdout);
     97     cin>>n>>m;
     98     build(1,1,n-1);
     99     for (i=1; i<=m; i++) {
    100         scanf("%d",&f);
    101         if (f==0) {
    102             scanf("%d%d%d%d%d",&l,&r,&a,&k,&p);
    103             if (l!=1)
    104                 add(1,1,n-1,l-1,l-1,a);
    105             if (l<=p-1)
    106                 add(1,1,n-1,l,p-1,k);
    107             if (p<=r-1)
    108                 add(1,1,n-1,p,r-1,-k);
    109             if (r!=n)
    110                 add(1,1,n-1,r,r,-a-(2*p-l-r)*k);
    111         } else {
    112             scanf("%d%d",&l,&r);
    113             if (l==r) printf("1
    ");
    114             else
    115                 printf("%d
    ",query(1,1,n-1,l,r-1).s+1);
    116         }
    117     }
    118 }
  • 相关阅读:
    并发编程三、线程可见性的底层原理
    并发编程二、线程的安全性和线程通信
    并发编程一、多线程的意义和使用
    Java进程监控
    分布式消息通信之RabbitMQ_Note
    分布式消息通信之RabbitMQ_02
    分布式消息通信之RabbitMQ_01
    分布式消息通信之RabbitMQ Tutorials
    SpringMVC重点分析
    Apache POI 4.0.1版本读取本地Excel文件并写入数据库(兼容 xls 和 xlsx)(五)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7677577.html
Copyright © 2011-2022 走看看