CSP模拟8
垫底了……垫底了……感觉这场真的好摆。垫底是必然的。一堆良心暴力都没打。
一眼望过去都可做但挂了又被一堆pj题薄纱。
排序是个好东西。它的作用已经不是一开始排个大小那么简单了,让区间有序可以便利很多操作。比如T2双指针不用担心 x 乱序的问题。T4的离线更简单的思考问题。有序的东西真的会方便思考,不会就排序。一些很常见的技巧见过但想不到。
似乎人人都喜欢有序的东西。
卡了根号的,没有关系我根号写挂了……
考虑枚举因数然后筛掉跟埃筛差不多。
要重新拿一个数组存a数组的出现,重新拿一个筛数,要不会多筛掉答案。
B.Dist Max 2
读错题,寄了,虽然只有一行的题干。
一眼二分答案。先对坐标按照x为第一关键字排序。维护双指针在区间[x,x+mid] 判断y是否合法。
Code
int check(int mid){
int mx=-1e9+7,mn=1e9+7;
for(int i=1,j=1;i<=n;i++){
while(j<i&&a[i].x-a[j].x>=mid){
mx=max(mx,a[j].y);
mn=min(mn,a[j].y);
j++;
}
if(mx-mid>=a[i].y)
return 1;
if(mn+mid<=a[i].y)
return 1;
}
return 0;
}
考试时忽略了下标的对应关系,做法一眼假。
重新思考check时忘记了可以排序,认为数据太乱不知所措(其实就是菜)。
xuany老师把线段树 x下处放上了 y 二分判断。
这也是处理二维数点的好方法。
跟昨天差不多的DP,但还是没写出来。
依旧是前面可以加 0 可以整体加 1 $ f _{i,j} = f _{i-1,j} + f _{i,j-i}$
但由于又个数限制所以不可以一直加1 所以 $ f _{i-1,j} $ 并不好控制。
开一个辅助数组 $ g _{i,j} 表示其没有0和为j的个数。g _{i,j} = f _{i,j-i} $ 那么 $ f _{i,j} = \Sigma _{k<=m} g[k][j] +f _{i,j-i} $ 可以前缀和优化。
Code
scanf("%lld%lld",&n,&m);
for(int i=0;i<=m;i++)
dp1[i][0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j>=i){
dp1[i][j]=dp1[i][j-i]%mod;
dp2[i][j]=dp1[i][j-i]%mod;
}
sum[i][j]=(sum[i-1][j]%mod+dp2[i][j]%mod)%mod;
dp1[i][j]=(dp1[i][j]%mod+(sum[i-1][j]%mod-sum[max(0,i-m-1)][j]%mod+mod)%mod+mod)%mod;
}
}
for(int i=1;i<=n;i++){
printf("%lld\n",dp2[i][n]%mod);
}
Julia the snail
只想到了离线扫描线,但没打。感觉这场真的好摆。
暴力是暴力跳绳。考虑优化暴力。
对于所有可以到r答案小与r的都附上r.好像是经典吉司机线段树。
oj数据不保证 r 唯一。oj开到1e6卡掉了分块。(不卡也不会)
Code
inline int max(int a,int b){
return a>b?a:b;
}
struct Ques{
int y,id;
};
vector <Ques> q[N];
int n,m,Q;
int ans[N];
int L[N];
struct Tree{
int mx,lastmx;
}t[N<<2];
inline void push_up(int k){
if(t[lc].mx==t[rc].mx){
t[k].mx=t[lc].mx;
t[k].lastmx=max(t[lc].lastmx,t[rc].lastmx);
}else if(t[lc].mx>t[rc].mx){
t[k].mx=t[lc].mx;
t[k].lastmx=max(t[lc].lastmx,t[rc].mx);
}else{
t[k].mx=t[rc].mx;
t[k].lastmx=max(t[lc].mx,t[rc].lastmx);
}
}
inline void push_down(int k){
if(t[lc].mx<t[k].mx&&t[lc].mx>t[k].lastmx)
t[lc].mx=t[k].mx;
if(t[rc].mx<t[k].mx&&t[rc].mx>t[k].lastmx)
t[rc].mx=t[k].mx;
}
void build(int k,int l,int r){
if(l==r){
t[k].mx=l;
return ;
}
int mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
push_up(k);
}
void update(int k,int l,int r,int L,int R,int val){
if(L<=l&&r<=R){
if(R>t[k].mx)
return;
if(t[k].mx>=R&&t[k].lastmx<R){
t[k].mx=val;
}else{
int mid=(l+r)>>1;
push_down(k);
update(lc,l,mid,L,R,val);
update(rc,mid+1,r,L,R,val);
push_up(k);
}
return ;
}
int mid=(l+r)>>1;
push_down(k);
if(L<=mid)
update(lc,l,mid,L,R,val);
if(R>mid)
update(rc,mid+1,r,L,R,val);
push_up(k);
}
int query(int k,int l,int r,int pos){
if(l==r){
return t[k].mx;
}
int mid=(l+r)>>1;
push_down(k);
if(pos<=mid)
return query(lc,l,mid,pos);
else
return query(rc,mid+1,r,pos);
}
int main(){
n=read(),m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
L[y]=x;
}
Q=read();
for(int i=1;i<=Q;i++){
int x=read(),y=read();
q[y].push_back((Ques){x,i});
}
build(1,1,n);
for(int i=1;i<=n;i++){
if(L[i]){
update(1,1,n,1,L[i],i);
}
if(!q[i].size())
continue;
for(int k=0;k<q[i].size();k++){
ans[q[i][k].id]=query(1,1,n,q[i][k].y);
}
}
for(int i=1;i<=Q;i++){
write(ans[i]);
}
return 0;
}
浙公网安备 33010602011771号