noip的题目都好长啊
懒得搬过来了
有需要的人自己去标题的网站上找吧
自己想的是nlogn的算法
对时间复杂度了解不够
以为可以通过
但实际上会T掉三个点
然后就去看了题解
推荐一篇特别好的博客http://www.cnblogs.com/ljh2000-jump/p/6189057.html
有详细说明是如何想到正解的
这里就不赘述了
发现很多题目套路都是先打部分分
打完部分分之后得到启发
进而打出正解
这题也是
根据部分分q=0时的单调性推出q!=时也具有单调性
——————————分割线———————————————
接下来让我哭诉一波(调这道题调了两三天啊)
然而我在vijos上a了之后
在bzoj上pe了无数次
终于把格式调对了之后
就WA了
然后就开始各种乱改
乱改一波long long后
发现同样的代码同样的数据
别人的电脑跑得跟我的不一样?
然后就重装一波编译器?
然后还是不一样?
于是放弃(有这方面知识的可以发评论告诉一波博主啊)
于是重新拿起我改之前的代码
交了一波uoj(感谢uoj感谢uoj感谢uoj)
然后也是前20个数据(估计可能是原题数据)全过
但它的extra data我就开始wa了
第一个wa点是精度问题
那一个*u/v的东西
我脑抽在他前面加了个*1.0
于是就变成浮点数了
于是就有浮点误差了
于是就wa了
这启示我们:一定要注意精度误差啊
第二个wa点:
一波大数据
这叫我怎么调!
于是认真研究了一份网上代码
发现唯一区别的地方可能就是取max的初值了
于是就把我的max=-1e9改成了max=-2*1e9
心里有点小忐忑
不会是因为这个吧
于是就交一波
于是就a了a了a了
太激动了
终于a了
仔细分析一波
队列里的元素确实有可能爆-1e9
这就提醒我们
写代码一定要分析全面
认真分析
然后有时分析不到地方
就只能靠你平时码风了
所以平时码风一定要好
所以记住:max一定要赋-inf max一定要赋-inf max一定要赋-inf
然后 inf一定要尽量小
——————————分割线———————————————
这是我T3个点85分的代码(堆,全局标记)
#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#include<cmath>
struct node
{
int x;
bool operator <(const node &k)
const
{
return x<k.x;
}
}e;
std::priority_queue<node>qu;
int read()
{
int ans=0;char t=getchar();
while(t>'9'||t<'0') t=getchar();
while(t<='9'&&t>='0') ans=ans*10+t-'0',t=getchar();
return ans;
}
int main()
{
int n=read(),m=read(),q=read(),u=read(),v=read(),t=read();int k;
double chu=u*1.0/v;
for(int i=1;i<=n;i++)
{
k=read(),qu.push((node){k});
}
int jia=0;
for(int i=1;i<=m;i++)
{
node a=qu.top(); qu.pop();
if(i%t==0) printf("%d ",a.x+jia);
int rr=(a.x+jia)*1.0*chu;
qu.push((node){rr-q-jia});
qu.push((node){a.x+jia-rr-q-jia});
jia+=q;
}
printf("\n");int sum=0;
while(!qu.empty())
{
sum++;
node a=qu.top(); qu.pop();
if(sum%t==0)printf("%d ",a.x+jia);
}
return 0;
}
还有ac的代码(有点丑)
#include<cstdio>
#include<cstring>
#include<algorithm>
int read()
{
int ans=0;char t=getchar();
while(t>'9'||t<'0') t=getchar();
while(t>='0'&&t<='9') ans=ans*10+t-'0',t=getchar();
return ans;
}
const int N=8*1e6;
int q1[N],q2[N],q3[N];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int n=read(),m=read(),q=read(),u=read(),v=read(),t=read();
for(int i=1;i<=n;i++)
scanf("%d",&q1[i]);
std::sort(q1+1,q1+1+n,cmp);
int head1=1,tail1=n,head2=1,tail2=0,head3=1,tail3=0,max;
int tag=0,maxi=0;
for(int i=1;i<=m;i++)
{
max=-2*1e9;maxi=0;
if(head1<=tail1&&q1[head1]>max) max=q1[head1],maxi=1;
if(head2<=tail2&&q2[head2]>max) max=q2[head2],maxi=2;
if(head3<=tail3&&q3[head3]>max) max=q3[head3],maxi=3;
int rr=( (long long ) (max+tag) )*u/v;
if(i%t==0)
printf(i+t>m?"%d":"%d ",max+tag);
if(maxi==1) head1++,q2[++tail2]=rr-tag-q,q3[++tail3]=max-rr-q;
else if(maxi==2) head2++,q2[++tail2]=rr-tag-q,q3[++tail3]=max-rr-q;
else head3++,q2[++tail2]=rr-tag-q,q3[++tail3]=max-rr-q;
tag+=q;
}
printf("\n");
int sum=1;
while((head1<=tail1)||(head2<=tail2)||(head3<=tail3))
{
max=-2*1e9;maxi=0;
if(head1<=tail1&&q1[head1]>max) max=q1[head1],maxi=1;
if(head2<=tail2&&q2[head2]>max) max=q2[head2],maxi=2;
if(head3<=tail3&&q3[head3]>max) max=q3[head3],maxi=3;
if(maxi==1) head1++;
else if(maxi==2) head2++;
else head3++;
if(sum%t==0) printf(sum+t>n+m?"%d":"%d ",max+tag);
sum++;
}
return 0;
}