zoukankan      html  css  js  c++  java
  • noi 2010 超级钢琴 划分树

    题意:小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐。 这架超级钢琴可以弹奏出n个音符,编号为1至n。第i个音符的美妙度为Ai,其中Ai可正可负。 一个“超级和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且不多于R。我们定义超级和弦的美妙度为其包含的所有音符的美妙度之和。两个超级和弦被认为是相同的,当且仅当这两个超级和弦所包含的音符集合是相同的。 小Z决定创作一首由k个超级和弦组成的乐曲,为了使得乐曲更加动听,小Z要求该乐曲由k个不同的超级和弦组成。我们定义一首乐曲的美妙度为其所包含的所有超级和弦的美妙度之和。小Z想知道他能够创作出来的乐曲美妙度最大值是多少。

    思路:划分树+priority_queue

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<cstdio>
      5 #include<queue>
      6 #include<algorithm>
      7 using namespace std;
      8 #define MAXN 510001
      9 struct node
     10 {
     11     int val[MAXN];
     12     int num[MAXN];
     13 }tree[22];
     14 struct heap
     15 {
     16     int num,k,val;
     17 };
     18 priority_queue<heap> Q;
     19 int n,m,L,R;
     20 int a[MAXN],sorted[MAXN],sum[MAXN];
     21 long long ans=0;
     22 bool operator < (const heap &A,const heap &B)
     23 {
     24     return A.val<B.val;
     25 }
     26 void build(int t,int left,int right)
     27 {
     28     if(left==right)
     29         return ;
     30     int mid=(left+right)/2;
     31     int i,isame=0,k1=left-1,k2=mid;
     32     for(i=left;i<=right;i++)
     33         if(tree[t].val[i]<sorted[mid])
     34             isame++;
     35     for(i=left;i<=right;i++)
     36     {
     37         if(tree[t].val[i]<sorted[mid])
     38             tree[t+1].val[++k1]=tree[t].val[i];
     39         else if(tree[t].val[i]>sorted[mid])
     40             tree[t+1].val[++k2]=tree[t].val[i];
     41         else if(isame<mid-left+1)
     42         {
     43             tree[t+1].val[++k1]=tree[t].val[i];
     44             isame++;
     45         }
     46         else
     47         {
     48             tree[t+1].val[++k2]=tree[t].val[i];
     49             isame++;
     50         }
     51         tree[t].num[i]=k1+1-left+tree[t].num[left-1];
     52     }
     53     build(t+1,left,mid);
     54     build(t+1,mid+1,right);
     55 }
     56 int search(int left,int right,int l,int r,int k,int t)
     57 {
     58     if(left==right)
     59        return tree[t].val[left];
     60     int mid=(left+right)/2;
     61     int temp=tree[t].num[r]-tree[t].num[l-1];
     62     int x=tree[t].num[l-1]-tree[t].num[left-1];
     63     int y=tree[t].num[r]-tree[t].num[left-1];
     64     if(temp>=k)
     65         return search(left,mid,left+x,left+y-1,k,t+1);
     66     else
     67         return search(mid+1,right,mid+l-left+1-x,mid+r-left+1-y,k-temp,t+1);
     68 }
     69 void solve()
     70 {
     71     int i;
     72     for(i=L+1;i<=n;i++)
     73     {
     74         heap temp;
     75         
     76         temp.val=sum[i]-search(1,n,max(i-R,1),max(i-L,1),1,1);
     77         temp.num=i;
     78         temp.k=1;
     79         Q.push(temp);
     80     }
     81     for(i=1;i<=m;i++)
     82     {
     83         heap temp=Q.top();
     84         Q.pop();
     85         ans+=temp.val;
     86         int x,y,t;
     87         t=temp.num;
     88         x=max(t-R,1); y=max(t-L,1);
     89         if(y-x+1<=temp.k)
     90             continue;
     91         temp.val=sum[t]-search(1,n,x,y,temp.k+1,1);
     92         temp.k++;
     93         Q.push(temp);
     94     }
     95     printf("%lld\n",ans);
     96 }
     97 int main()
     98 {
     99     memset(tree,0,sizeof(tree));
    100     sorted[1]=sum[1]=0;
    101     scanf("%d%d%d%d",&n,&m,&L,&R);
    102     int i;
    103     for(i=1;i<=n;i++)
    104     {
    105         scanf("%d",a+i);
    106         sum[i+1]=sum[i]+a[i];
    107         sorted[i+1]=tree[1].val[i+1]=sum[i+1];
    108     }
    109     n++;
    110     sort(sorted+1,sorted+n+1);
    111     build(1,1,n);
    112     solve();
    113     return 0;
    114 }
  • 相关阅读:
    Go基础系列:双层channel用法示例
    shell脚本动画小工具
    Go基础系列:channel入门
    python面向对象入门(1):从代码复用开始
    python包导入细节
    python模块导入细节
    Go基础系列:读取标准输入
    黄聪:C#获取网页HTML内容的三种方式
    黄聪:如何正确在Vue框架里使用Swiper
    黄聪:C#使用GeckoFx拦截监控Http数据
  • 原文地址:https://www.cnblogs.com/myoi/p/2586974.html
Copyright © 2011-2022 走看看