zoukankan      html  css  js  c++  java
  • [权值线段树] Jzoj P4270 魔道研究

    Description

    “我希望能使用更多的魔法。不对,是预定能使用啦。最终我要被大家称呼为大魔法使。为此我决定不惜一切努力。”
    ——《The Grimoire of Marisa》雾雨魔理沙
    魔理沙一如既往地去帕秋莉的大图书馆去借魔导书(Grimoire) 来学习魔道。
    最开始的时候,魔理沙只是一本一本地进行研究。然而在符卡战中,魔理沙还是战不过帕秋莉。
    好在魔理沙对自己的借还和研究结果进行了记录,从而发现了那些魔导书的精妙之处。
    帕秋莉的那些魔导书,每本都有一个类别编号ti 和威力大小pi。而想要获得最有威力的魔法,就必须同时研究一些魔导书。而研究的这些魔导书就必须要满足,类别编号为T 的书的本数小于等于T,并且总共的本数小于等于一个给定的数N。而研究这些魔导书之后习得的魔法的威力就是被研究的魔导书的威力之和。
    为了击败帕秋莉,魔理沙想要利用自己发现的规律来获得最有威力的魔法。
    她列出了计划中之后M 次的借还事件,并想要知道每个事件之后自己所能获得的魔法的最大威力。可她忙于魔法材料——蘑菇的收集,于是这个问题就交给你来解决了。
     

    Input

    输入文件grimoire.in。
    第1 行2 个整数N,M,分别表示魔理沙能研究的魔导书本数的上限和她的借还事件数。
    之后M 行,每行的形式为“op t p”(不含引号)。Op 为“BORROW” 或“RETURN”,分别表示借书和还书。T 为一个整数,表示这本书的类别编号。P为一个整数,表示这本书的威力大小。注意,还书时如果有多本书满足类别编号为t,威力大小为p,这表明这些书都是相同的,魔理沙会任选其中一本书还回去。如果你问我为何会有相同的书,多半因为这是魔导书吧。

    Output

    输出文件grimoire.out。
    一共M 行,每行一个整数,即每个事件之后的最大威力。
     

    Sample Input

    5 10 
    BORROW 1 5811 
    BORROW 3 5032
    RETURN 3 5032 
    BORROW 3 5550 
    BORROW 5 3486 
    RETURN 1 5811 
    RETURN 3 5550 
    BORROW 4 5116 
    BORROW 3 9563 
    BORROW 5 94

    Sample Output

    5811
    10843
     5811
    11361
    14847
    9036
    3486
    8602
    18165
    18259
     

    Data Constraint

    对于5% 的数据,1 <= t,N,M <= 50。
    对于10% 的数据,1 <= t,N,M <= 100。
    对于30% 的数据,1 <= t,N,M<= 10 000。
    另有30% 的数据,1 <= p <= 1 000。
    对于100% 的数据,1 <= t,N,M <= 300 000,1<= p<= 1 000 000 000。
    另外,总共有30% 的数据,满足没有“RETURN” 操作。这部分数据均匀分布。

    题解

    • 题目大意:有两个操作,①“BORROW”,加入一本i种类的书,它的威力为j  ②“RETURN”,换一本种类i威力j的书
    • 每次输出前N大的书的威力和(要求i种类的书的数量不能大与i)
    • 其实有点像区间第k大的意思,第一眼感觉是数据结构乱搞
    • 这题正解是权值线段树+动态开点
    • "权值线段树"就是在线段树的基础上用数字当下标
    • 考虑一下如何去做
    • 对于一次“BORROW”操作,其实就是找到第N个大的,且要合法的
    • 如果第N的大的比新加入的点小,可以将第N大的点从前N大踢出,将新点打入
    • 对于一次“RETURN”操作,其实就是找到第N+1个大的
    • 将其加入,将要还的书踢出(如果在前N大)
    • 注意MLE,所以要动态开点

    代码

     1 #include<cstdio> 
     2 #include<algorithm>
     3 using namespace std;
     4 const int N=300010*2,inf=1000000000;
     5 int tot,root[N],num[N],left[N],right[N];
     6 long long ans,sum[300010];
     7 char ch;
     8 void add(int &x,int l,int r,int k,int f)
     9 {
    10     if (!x) x=++tot;
    11     if (f) num[x]++,sum[x]+=k; else num[x]--,sum[x]-=k;
    12     if (l==r) return;
    13     int mid=(l+r)/2;
    14     if (k<=mid) add(left[x],l,mid,k,f); else add(right[x],mid+1,r,k,f);
    15 }
    16 int query(int x,int l,int r,int k)
    17 {
    18     if (l==r)
    19     {
    20         ans+=min(k,num[x])*l;
    21         return l;
    22     }
    23     int mid=(l+r)/2;
    24     if (num[right[x]]>=k) return query(right[x],mid+1,r,k);
    25     else 
    26     {
    27         ans+=sum[right[x]];
    28         return query(left[x],l,mid,k-num[right[x]]);
    29     }
    30 }
    31 int main()
    32 {
    33     freopen("grimoire.in","r",stdin);
    34     freopen("grimoire.out","w",stdout);
    35     int n,m,x,y;
    36     scanf("%d%d",&n,&m);
    37     for (int i=1;i<=m;i++)
    38     {
    39         scanf("%c",&ch);
    40         if (ch=='B')
    41         {
    42             scanf("ORROW %d %d
    ",&x,&y);
    43             int k=query(root[x],0,inf,x);
    44             add(root[x],0,inf,y,1);
    45             if (y>=k)
    46             {
    47                 add(root[0],0,inf,y,1);
    48                 add(root[0],0,inf,k,0);
    49             }
    50         }
    51         else 
    52         {
    53             scanf("ETURN %d %d
    ",&x,&y);
    54             int k=query(root[x],0,inf,x+1);
    55             add(root[x],0,inf,y,0);
    56             if (y>=k)
    57             {
    58                 add(root[0],0,inf,y,0);
    59                 add(root[0],0,inf,k,1);
    60             }
    61         }
    62         ans=0;
    63         query(root[0],0,inf,n);
    64         printf("%lld
    ",ans);
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    1.2 偏差与方差
    深度学习中Xavier初始化
    1.1 训练/开发/测试集
    Python笔记(5)类__方法与继承
    Python笔记(4)类__属性与描述符
    Python笔记(3)迭代器与生成器
    Python笔记(2)函数
    线性回归 Linear Regression
    Python笔记(1)变量与表达式
    跳转到某个Activity
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9301524.html
Copyright © 2011-2022 走看看