社区讨论
关于用堆卡常
P2827[NOIP 2016 提高组] 蚯蚓参与者 5已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @mk7rmkie
- 此快照首次捕获于
- 2026/01/10 11:48 上个月
- 此快照最后确认于
- 2026/01/12 19:45 上个月
我通过P5282中的卡常技巧以及查阅的资料终于用16叉堆和AVX512卡过了本题,代码如下。
CPP#include<bits/extc++.h>
#include<immintrin.h>
#pragma GCC target("avx512f")
using namespace std;
namespace IO
{
const int SIZE=1<<22;
char buf[SIZE],*p1=buf,*p2=buf,outbuf[SIZE],*p3=outbuf;
__attribute__((always_inline)) inline char gc()
{
if(p1==p2)
{
p2=(p1=buf)+fread(buf,1,SIZE,stdin);
if(p1==p2) return EOF;
}
return *p1++;
}
__attribute__((always_inline)) inline int read()
{
int res=0;
char c=gc();
while(c<'0' || c>'9') c=gc();
while(c>='0' && c<='9' && c!=EOF) res=(res<<1)+(res<<3)+(c^48),c=gc();
return res;
}
__attribute__((always_inline)) inline void pc(char c)
{
if(p3-outbuf==SIZE)
{
fwrite(outbuf,1,SIZE,stdout);
p3=outbuf;
}
*p3++=c;
}
__attribute__((always_inline)) inline void write(int x)
{
if(x==0) return pc('0'),void();
int num[50],cnt=0;
while(x) num[++cnt]=x%10,x/=10;
for(int i=cnt;i>=1;i--) pc(num[i]+'0');
}
__attribute__((always_inline)) inline void flush()
{
fwrite(outbuf,1,p3-outbuf,stdout);
p3=outbuf;
}
}
using namespace IO;
int a[7110010]__attribute__((aligned(64)));
int cnt;
__attribute__((always_inline)) inline void push(int x)
{
int cur=++cnt;
while(__builtin_expect(cur>1,1))
{
int p=((cur-2)>>4)+1;
if(a[p]>=x) break;
a[cur]=a[p];
cur=p;
}
a[cur]=x;
}
__attribute__((always_inline)) inline void down(int u)
{
int x=a[u],c;
while(1)
{
c=((u-1)<<4)+2;
if(c>cnt) break;
int maxidx=c;
if(__builtin_expect(c+15<=cnt,1))
{
__m512i v=_mm512_loadu_si512((__m512i*)&a[c]);
int mv=_mm512_reduce_max_epi32(v);
unsigned int mask=_mm512_cmpeq_epi32_mask(v,_mm512_set1_epi32(mv));
maxidx=c+__builtin_ctz(mask);
}
else for(int i=c+1;i<=cnt;i++) if(a[i]>a[maxidx]) maxidx=i;
if (x>=a[maxidx]) break;
a[u]=a[maxidx];
u=maxidx;
}
a[u]=x;
}
__attribute__((always_inline)) inline void pop()
{
a[1]=a[cnt--];
down(1);
}
int n,m,q,u,v,t,all;
int main()
{
n=read(),m=read(),q=read(),u=read(),v=read(),t=read();
for(int i=1;i<=n;i++) a[i]=read();
cnt=n;
for(int i=(cnt-2)/16+1;i>=1;i--) down(i);
int next=t;
long double p=(long double)u/v;
for(int i=1;i<=m;i++)
{
int top=a[1]+all;
int q1=int(top*p),q2=top-q1;
all+=q;
a[1]=q1-all;
down(1);
push(q2-all);
if(__builtin_expect(i==next,0)) write(top),pc(' '),next+=t;
}
pc('\n');
next=t;
for(int i=1;cnt;i++,pop()) if(__builtin_expect(i==next,0)) write(a[1]+all),pc(' '),next+=t;
flush();
return 0;
}
话说有没有能不用指令集通过的写法,毕竟CCF不给用。
回复
共 8 条回复,欢迎继续交流。
正在加载回复...