zoukankan      html  css  js  c++  java
  • 【BZOJ 3443】 3443: 装备合成 (离线+线段树)

    3443: 装备合成

    Time Limit: 15 Sec  Memory Limit: 128 MB
    Submit: 63  Solved: 31

    Description

    【背景】
        lll6924在某游戏中有n件装备。
    【描述】
        游戏中共有m种属性,装备有属性加成。当将A装备合成到B装备上时,A装备消失,B装备的所有小于A装备的属性更新为A装备的这个属性。然而lll6924的记性不太好,因为装备很多,所以一些属性常常记错,他在合成时会突然想起,某个装备的某个属性的初始值应该是多少(暂且认为修改后是正确的,这个属性可能会被修改多次)(请注意,这是理解题意的难点,请结合样例)。在合成过程中lll6924想知道一些装备的一些属性(根据之前给出的数据(初始属性、合成、修改),输出装备当前认为是正确的属性)。

    Input

        输入有n+1+q行,第一行有三个用空格隔开的正整数n、m、q,q表示操作(合成操作、询问操作和修改操作)数。接下来的n行,每行有m个用空格隔开的正整数,表示这个装备的各个属性。接下来的q行,每行格式为“k a b c”,若k为1,则为将第a个装备合成到第b个装备,输入数据保证a、b装备存在,此时c=0。若k为2,则为询问第a个装备的第b个属性(若第a个装备已被合成掉,则输出该装备在被合成前的第b个属性是多少),此时c=0。若k为3,则为将第a个装备的第b个属性的初始值更新为c(注意,若a装备已被合成掉,该操作仍然有效,会影响他合成到的装备的属性)。

    Output

        输出如输入格式所述,每个输出占一行。

    Sample Input

    3 5 10
    1 2 3 4 3
    0 0 0 0 0
    2 0 0 0 0
    1 1 2 0
    2 2 3 0
    3 2 4 5
    1 2 3 0
    3 1 3 2
    2 3 1 0
    3 3 1 0
    2 3 1 0
    2 3 4 0
    2 2 3 0

    Sample Output

    3
    2
    1
    5
    2
    【数据范围及约定】
    100%的数据,0<n≤1500,0<m≤400,0<q≤200000,0≤装备属性≤50000。

    HINT

    Source

    【分析】

      突然爱上可以离线的题。。

      【上面那题强制在线spaly还不会做啊啊啊

      这题,跟BZOJ2333差不多啊,就是先把树建出来,然后弄dfs序,再用线段树维护。

      建树就是按时间顺序,两个合并的时候弄一个新的点,询问的时候就问新的这个点。

    T了之后乱开数组范围了ORZ。。【发现我数组范围永远开不对。。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<cmath>
      7 using namespace std;
      8 #define Maxn 1000010
      9 #define Mn 1010
     10 
     11 int a[Maxn],pos[Maxn],b[Maxn];
     12 int rt[Mn],ft[Mn],add[Mn];
     13 int sq;
     14 
     15 bool cmp(int x,int y) {return x>y;}
     16 
     17 void upd(int x)
     18 {
     19     for(int i=ft[x];i<=rt[x];i++) b[i]=a[i];
     20     sort(b+ft[x],b+1+rt[x],cmp);
     21 }
     22 
     23 void change(int x,int y,int c)
     24 {
     25     if(pos[x]==pos[y])
     26     {
     27         for(int i=x;i<=y;i++) a[i]+=c;
     28         upd(pos[x]);
     29     }
     30     else
     31     {
     32         for(int i=x;i<=rt[pos[x]];i++) a[i]+=c;
     33         for(int i=ft[pos[y]];i<=y;i++) a[i]+=c;
     34         for(int i=pos[x]+1;i<pos[y];i++) add[i]+=c;
     35         upd(pos[x]);upd(pos[y]);
     36     }
     37 }
     38 
     39 int ffind(int x,int y)
     40 {
     41     int l=ft[x],r=rt[x];
     42     if(b[l]+add[x]<y) return 0;
     43     while(l<r)
     44     {
     45         int mid=(l+r+1)>>1;
     46         if(b[mid]+add[x]>=y) l=mid;
     47         else r=mid-1;
     48     }
     49     return l-ft[x]+1;
     50 }
     51 
     52 int query(int x,int y,int c)
     53 {
     54     int ans=0;
     55     if(pos[x]==pos[y])
     56     {
     57         for(int i=x;i<=y;i++) if(a[i]+add[pos[i]]>=c) ans++;
     58     }
     59     else
     60     {
     61         for(int i=x;i<=rt[pos[x]];i++) if(a[i]+add[pos[x]]>=c) ans++;
     62         for(int i=ft[pos[y]];i<=y;i++) if(a[i]+add[pos[y]]>=c) ans++;
     63         for(int i=pos[x]+1;i<pos[y];i++) ans+=ffind(i,c);
     64     }
     65     return ans;
     66 }
     67 
     68 int main()
     69 {
     70     int n,q;
     71     scanf("%d%d",&n,&q);
     72     sq=(int)ceil(sqrt((double)n));
     73     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
     74     for(int i=1;i<=n;i++) b[i]=a[i];
     75     for(int i=1;i<=n;i++) pos[i]=(i-1)/sq+1;
     76     for(int i=1;i<n;i++) if(pos[i]!=pos[i+1]) rt[pos[i]]=i,ft[pos[i+1]]=i+1;
     77     ft[1]=1;rt[pos[n]]=n;
     78     for(int i=1;i<=pos[n];i++) add[i]=0;
     79     for(int i=1;i<=pos[n];i++) sort(b+ft[i],b+rt[i]+1,cmp);
     80     /*printf("sq = %d
    ",sq);
     81     for(int i=1;i<=n;i++) printf("%d ",pos[i]);printf("
    ");
     82     for(int i=1;i<=sq;i++) printf("%d ",ft[i]);printf("
    ");
     83     for(int i=1;i<=sq;i++) printf("%d ",rt[i]);printf("
    ");*/
     84     // while(1);
     85     for(int i=1;i<=q;i++)
     86     {
     87         char s[10];    
     88         int x,y,c;
     89         scanf("%s%d%d%d",s,&x,&y,&c);
     90         if(s[0]=='M')
     91         {
     92             change(x,y,c);
     93         }
     94         else
     95         {
     96             printf("%d
    ",query(x,y,c));
     97         }
     98     }
     99     return 0;
    100 }
    View Code

    2017-03-27 22:08:51

  • 相关阅读:
    MySQL错误 1030-Got error 28 from storage engine
    电脑开机无反应 不显示BIOS 硬件没问题
    python错误 import: unable to open X server
    Python 错误 invalid command 'bdist_wheel' & outside environment /usr
    Cento 7安装 Failed to execute /init
    笔记《鸟哥的Linux私房菜》5 首次登入与在线求助 man
    Scrapy XPath语法
    Linux 用户操作
    Mysql 表修改
    Ubuntu 配置 Python环境 IPython
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6629108.html
Copyright © 2011-2022 走看看