• *LOJ#2306. 「NOI2017」蔬菜


    $n leq 100000$种蔬菜,每个蔬菜有:一单位价格;卖第一单位时额外价格;总量;每天腐烂量。每天能卖$m leq 10$单位蔬菜,多次询问:前$k leq 100000$天最多收入多少。价格、量$ leq 1e9$。

    我也不知道为啥88分QAQ 求大佬看看啊

    把第一单位蔬菜和其他的拆开,记下他们“能卖的最后一天”,假设第一单位蔬菜比其他的要晚卖。这样,按价格排序后,只需要贪心地填入能填的最晚的一天就好了。找最晚的一天用并查集。这样就求出了天数不限时的答案。

    要求有限天数内的答案,只需要从天数不限往前推,推的过程中把最便宜的那些丢掉就好了。(可以想象把多出来的空用贵的菜补上)

     1 //#include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 //#include<math.h>
     5 //#include<set>
     6 //#include<queue>
     7 //#include<bitset>
     8 //#include<vector>
     9 #include<algorithm>
    10 #include<stdlib.h>
    11 using namespace std;
    12 
    13 #define LL long long
    14 int qread()
    15 {
    16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
    17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
    18 }
    19 
    20 //Pay attention to '-' , LL and double of qread!!!!
    21 
    22 int n,m,K;
    23 #define maxn 200011
    24 struct Node{int v,day,tot,c,id; bool operator < (const Node &b) const {return v>b.v;} }p[maxn]; int lp=0;
    25 
    26 int dd[maxn],ufs[maxn];
    27 int find(int x) {return x==ufs[x]?x:(ufs[x]=find(ufs[x]));}
    28 void Union(int x,int y) {x=find(x); y=find(y); if (x!=y) ufs[x]=y;}
    29 //zhu yi da de bing dao xiao de
    30 
    31 LL ans[maxn]; int list[maxn*10],len=0;
    32 int main()
    33 {
    34 //    freopen("in.txt","r",stdin);
    35     n=qread(); m=qread(); K=qread();
    36     for (int i=1;i<=100000;i++) ufs[i]=i,dd[i]=m;
    37     //我的t是他的c,我的c是他的x。。。。。 
    38     for (int i=1,a,s,c,t;i<=n;i++)
    39     {
    40         a=qread(); s=qread(); t=qread(); c=qread();
    41         //一种蔬菜拆两种 
    42         if (c)
    43         {
    44             p[++lp]=(Node){a+s,t/c+(t%c>0),1,0,i};
    45             if (t>1) p[++lp]=(Node){a,(t-1)/c+((t-1)%c>0),t-1,c,i};
    46         }
    47         else
    48         {
    49             p[++lp]=(Node){a+s,-1,1,0,i};
    50             if (t>1) p[++lp]=(Node){a,-1,t-1,c,i};
    51         }
    52     }
    53     sort(p+1,p+1+lp);
    54     
    55     //贪心放,每个蔬菜如果x>0就从“能放的最后一天”开始往前,不然就从100000开始往前放 
    56     LL Ans=0; int TT=0;
    57     for (int i=1;i<=lp;i++)
    58     {
    59         int v=p[i].v,day=p[i].day,tot=p[i].tot,c=p[i].c;
    60 //        cout<<day<<endl;
    61         LL able=~day?(tot-(day-1)*c):0x3f3f3f3f; int now=find(~day?min(day,100000):100000);
    62         
    63         //now 是哪一天,dd 是每天剩多少可以放, tot是这菜还剩多少,able是一个后缀最多放多少菜
    64         //able就是原来总蔬菜量减掉前now-1天的腐烂量剩下的,随着now变小会变大,要排除掉后面已经放了的 
    65          
    66         while (tot && now)
    67         {
    68 //        cout<<able<<' '<<now<<endl;
    69             int can=min(min((LL)tot,able),(LL)dd[now]);
    70             //can是在now这天能放的量 
    71             dd[now]-=can; Ans+=can*1ll*v;
    72             if (dd[now]==0) Union(now,now-1);
    73             int tn=find(now-1); able+=1ll*c*(now-tn)-can; now=tn; tot-=can; TT+=can;
    74             for (int j=1;j<=can;j++) list[++len]=v;
    75             //list是把真正选中的菜按价格递减放的,偷懒就直接开个大数组丢进去了 
    76         }
    77 //        cout<<i<<' '<<p[i].v<<' '<<tot<<' '<<p[i].id<<' '<<"ANS"<<Ans<<endl;
    78 //        for (int j=1;j<=20;j++) cout<<dd[j]<<' ';cout<<endl<<endl;
    79     }
    80     
    81     //怀疑上面就错了,用菜总量<=10000的数据算100000天的答案是不对的 
    82     
    83     //往前推前面的答案 
    84     int tmp;
    85     ans[tmp=TT/m+(TT%m>0)]=Ans;
    86 //    cout<<"tmp"<<tmp<<' '<<"TT"<<TT<<endl;
    87     for (int i=tmp+1;i<=100000;i++) ans[i]=ans[i-1];
    88     ans[tmp-1]=ans[tmp]; for (int i=TT;i>TT-((TT-1)%m+1);i--) ans[tmp-1]-=list[len--];
    89     for (int i=tmp-1;i;i--)
    90     {
    91         ans[i-1]=ans[i];
    92         for (int j=1;j<=m;j++) ans[i-1]-=list[len--];
    93     }
    94     
    95     for (int i=1;i<=K;i++) printf("%lld
    ",ans[qread()]);
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    一款JS+CSS实现的无缝平滑图片滚动代码
    2个按钮控制的左右图片滚动特效代码
    JS+CSS控制左右切换鼠标可控的无缝图片滚动代码
    用CSS实现图片水印效果代码
    用鼠标拖动图片的JS代码
    一款实用的JavaScript图片幻灯片代码
    摘自搜狐女人频道的图片切换的JS代码
    JS防PS里的图片拖拉缩放效果代码
    鼠标移至图片后抖动的JS代码
    WINDOWS补丁的多线程下载方法和安装技巧
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9251482.html
Copyright © 2020-2023  润新知