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(" ");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(" "); 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; }