省选前的JOI

RT,发现找不到题,于是又开了新坑

(省选前到处挖坑2333)


JOI 2017 Final

焚风现象

普及组差分好题

(不是看到200ms就tm线段树去了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=100005;
 6 long long ans,dif[N];
 7 int n,m,s,t,t1,t2,t3,rd,lst; 
 8 int main()
 9 {
10     scanf("%d%d%d%d",&n,&m,&s,&t);
11     scanf("%d",&rd);
12     for(int i=1;i<=n;i++)
13     {
14         scanf("%d",&rd);
15         dif[i]=rd-lst,lst=rd; 
16         ans-=(dif[i]>0)?(1ll*s*dif[i]):(1ll*t*dif[i]);
17     }
18     for(int i=1;i<=m;i++)
19     {
20         scanf("%d%d%d",&t1,&t2,&t3);
21         ans+=(dif[t1]>0)?(1ll*s*dif[t1]):(1ll*t*dif[t1]);
22         dif[t1]+=t3;
23         ans-=(dif[t1]>0)?(1ll*s*dif[t1]):(1ll*t*dif[t1]);
24         if(t2!=n)
25         {
26             t2++;
27             ans+=(dif[t2]>0)?(1ll*s*dif[t2]):(1ll*t*dif[t2]);
28             dif[t2]-=t3;
29             ans-=(dif[t2]>0)?(1ll*s*dif[t2]):(1ll*t*dif[t2]);
30         }
31         printf("%lld\n",ans);
32     }
33     return 0;
34 }
View Code

准高速电车

观察性质以进行贪心

题意可能有那么一点糊,其实是你可以走多次然后求和,只要每次都不超过T即可

注意题目保证速度按常识给出

我们发现一次出行一定是先坐快车,然后换乘准快车,最后坐慢车。而且显然我们最后一次一定是从一个快车站开始然后到不了下一个快车站的,所以我们只要考虑两两相邻的快车站中间即可

那我们就先只考虑一对相邻的快车站且我们在中间结束的情况,我们现在要在中间放一些准快车站,而我们选择在哪个准快车站结束相当于在后面一段用剩下的时间对右侧进行了一个覆盖,且这个覆盖的长度单调不升(显然越到后面剩的时间越少)。同样显然的是覆盖不会相交(否则不优)且一个覆盖的结束与下一个准快车站(如果还有的话)是相邻的(否则也不优)。于是问题变成了贪心,用堆维护每对相邻的快车站里准快车站覆盖的区间即可,记录剩余时间,剩余车站数和覆盖的长度,贪心选覆盖长度前k大的并每次更新

注意如果用高速能跑完相当于最后一个闭合了,答案+1

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define lli long long
 6 using namespace std;
 7 const int N=3005;
 8 struct node
 9 {
10     lli tim;
11     int len,mxl;
12 };
13 bool operator < (node x,node y)
14 {
15     return x.len<y.len;
16 }
17 int n,m,k,a,b,c,ans,s[N];
18 lli T; priority_queue<node> hp;
19 void Insert(lli t,int l,int k)
20 {
21     if(t<0||l<0) return;
22     int cov=min(t/a,(lli)l)+1;
23     if(k) ans+=cov,Insert(t-1ll*cov*c,l-cov,0);
24     else hp.push((node){t,cov,l});
25 }
26 int main()
27 {
28     scanf("%d%d%d",&n,&m,&k),k-=m;
29     scanf("%d%d%d%lld",&a,&b,&c,&T);
30     for(int i=1;i<=m;i++) scanf("%d",&s[i]);
31     for(int i=1;i<m;i++) Insert(T-1ll*(s[i]-1)*b,s[i+1]-s[i]-1,1);
32     while(!hp.empty()&&k--)
33     {
34         node tn=hp.top(); hp.pop();
35         Insert(tn.tim,tn.mxl,1);
36     }
37     printf("%d",ans-1+(1ll*(s[m]-1)*b<=T));
38     return 0;
39 }
View Code

猜你喜欢

转载自www.cnblogs.com/ydnhaha/p/10618048.html