mmt

居然第一步膜化乘除 都没看出来,没救了...

大概是贡献前缀和优化的做法

巨兔式讲解:大家都学会了么?

咱发现有大量的 (i/j , i%j ) 同时 对很多 c 产生了贡献,咱可以去优化这一部分的转移,具体做法就是根据前面能加的后面也能加,然后一路累加且算贡献

对于小于根号的所有 i/j ,咱可以优化这一部分转移,然后对于大于根号的 i/j ,暴力算就好了,两者复杂度都是是 n 根号 n 的

//by Judge
#include<bits/stdc++.h>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define ll long long
#define eps 1e-8
using namespace std;
const int mod=123456789;
const int M=1e5+3;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline int read(){ int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(int x,char chr='\n'){
if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int n,bl; arr a,b,c; double inv[M];
#define Div(x,y) (int(x*inv[y]+eps))
int main(){ n=read(),bl=sqrt(n);
fp(i,1,n) inv[i]=1.0/i,a[i]=read(); fp(i,0,n-1) b[i]=read();
fp(x,1,bl) fp(y,0,x-1){ Rg ll now=-1; Rg int A,l,r; // i/j = x 步长 , y 初始位置
for(Rg int k=x+y;k<=n;k+=x) if(Div(k,Div(k,x))==x){ // 必须是可达状态 ,此时 j = k/x
if(now<0) l=r=Div(k,x),A=k%r,now=1ll*a[x]*b[A]%mod;
else{ ++r; if(Div(k,l)!=i) ++l; else A=k%l,now=(now+1ll*a[x]*b[A])%mod; }
c[k]=(c[k]+now)%mod; // 当前的 now 存在的之前的状态当前 k 也可达
}
}
fp(i,1,n) fp(j,1,i) if(Div(i,j)<=bl) break;
else c[i]=(c[i]+1ll*a[Div(i,j)]*b[i%j]%mod)%mod;
fp(i,1,n) print(c[i]); return Ot(),0;
}

Sabotage

艹...这 T2 ,真 tm 长芝士了 ,支配树的新奇打法...

一眼看不出是支配树,只觉得题面眼熟,然后发现其实算法更加熟...

然后发现支配树代码很长,调挂了,于是康康题解区对比找找自己哪里挂了,于是有了这次惊人的发现

可以说是支配树板子题辣,这里的常规做法就不说了,又臭又长 (艹)

这里用的方法很诡(qiao)异(miao),大概就是说咱把这个 DAG 缩一下,对于入度大于 2 的节点把 Fa 设为 所有父亲节点的 LCA ,求解的时候输出两个点 LCA 的深度就好了,至于两个点不在同一棵树上(或者是别的无解情况),是可以被非常自然的处理掉的(雾),于是正确性就有了感性理解下的保证

然后咱可以发现这里的 LCA 是要随着拓扑的进行可以同时维护的...所以就打不了小常数的树剖了,于是顺便重温了一下倍增 LCA (雾)

具体康康代码咯?

卡了下常,进了 Rank1 (可能您康到咱的代码之后就不是了)

//by Judge
#include<cstdio>
#include<iostream>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(Rg int i=head[u],v=e[i].to;i;v=e[i=e[i].nxt].to)
using namespace std;
const int M=1e5+7;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline int read(){ int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int C=-1,Z;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
inline void print(int x,char chr='\n'){
if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]=chr;
} int n,m,pat,hd,tl,f[M][19]; arr head,lg,q,h,d;
struct Edge{ int to,nxt; }e[M<<1];
inline void add(int x,int y){ ++d[y];
e[++pat]=(Edge){y,head[x]},head[x]=pat;
}
inline int LCA(int u,int v){ if(h[u]>h[v]) swap(u,v);
for(Rg int i=0;h[v]-h[u];++i) if(((h[v]-h[u])>>i)&1) v=f[v][i]; if(u==v) return u;
fd(i,17,0) if(f[u][i]^f[v][i]) u=f[u][i],v=f[v][i]; return *f[u];
}
int main(){ n=read(),m=read(),lg[0]=-1;
Rg int x,y; fp(i,1,m) x=read(),y=read(),add(y,x);
fp(i,1,n) lg[i]=lg[i>>1]+1,*f[i]=!d[i]?q[++tl]=i,0:-1;
while(hd<tl){ x=q[++hd],h[x]=h[*f[x]]+1;
fp(i,1,lg[h[x]]) f[x][i]=f[f[x][i-1]][i-1];
go(x) *f[v]=*f[v]<0?x:LCA(x,*f[v]),!--d[v]&&(q[++tl]=v);
} m=read(); while(m--) x=read(),y=read(),print(h[LCA(x,y)]);
return Ot(),0;
}

LP

并没有什么特别的? 但是咱太菜了还是想不出来的那种

(看了题解后)不难想出 \(n*p^2\) 的 SB dp 方程 ,f[i][j][k]

看着数据范围应该是 np 的题目(NP-hard 可海星),那么怎么少掉一个 p ?

咱发现两个限制本质上是可以简化的,可以把 f 简化为 2 维的 f[i][j] ,j 表示对于选出的 b 之和小于等于 j 且 c 之和大于等于 j

然后两个转移方式(x 为 0 或 1)的 dp 转移,然后一个单调队列优化 x=1 时的转移就好了

空间继续优化,那么滚动可以解决,并且开数组变小了,代码常数却并没有怎么提高,所以隐隐起到了卡常的效果(空间小一般时间也会小,原因显而易见)

//by Judge
#include<cstdio>
#include<cstring>
#include<iostream>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define QwQ printf("IMPOSSIBLE!!!\n")
#define QvQ printf("%d\n",f[n&1][p])
using namespace std;
const int inf=2e9+7;
const int M=1e4+3;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline bool cmin(int& a,int b){return a>b?a=b,1:0;}
inline int read(){ int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} int n,p,head,tail,x,y; arr a,b,c,f[2],q,w;
inline void Solv(){ n=read(),p=read(); fp(i,1,n) a[i]=read();
fp(i,1,n) b[i]=read(); fp(i,1,n) c[i]=read(); fp(i,1,p) f[0][i]=inf;
fp(i,1,n){ head=1,tail=0,x=i&1,y=x^1; fp(j,0,p) f[x][j]=f[y][j];
fp(j,a[i],p){ while(head<=tail&&w[tail]>=f[y][j-a[i]]) --tail;
while(head<=tail&&q[head]<j-b[i]) ++head;
q[++tail]=j-a[i],w[tail]=f[y][q[tail]],cmin(f[x][j],w[head]+c[i]);
}
} f[n&1][p]<inf?QvQ:QwQ;
}
int main(){ int T=read();
while(T--) Solv(); return 0;
}

明天继续吧...

CSP-S全国模拟赛第三场 【nan死了】的更多相关文章

  1. 【noi.ac-CSP-S全国模拟赛第三场】#705. mmt

    给定数组a[],b[] 求$$c_i=\sum_{j=1}^{i} a_{\left \lfloor \frac{n}{j} \right \rfloor}·b_{i \bmod j}$$ 大概就是对 ...

  2. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

  3. [NOI.AC 2018NOIP模拟赛 第三场 ] 染色 解题报告 (DP)

    题目链接:http://noi.ac/contest/12/problem/37 题目: 小W收到了一张纸带,纸带上有 n个位置.现在他想把这个纸带染色,他一共有 m 种颜色,每个位置都可以染任意颜色 ...

  4. CSP-S全国模拟赛第四场 【nan?】

    本来想抢三题的 rk1 ?[无耻 最后发现 T2 好像还是慢了些,只搞了个 rk2 子段与子段 第一题随便分析一下,发现一段区间中某个元素的贡献次数就是 \((x+1)·(y+1)\) x 是他左边的 ...

  5. NOI2019省选模拟赛 第三场

    传送门 明明没参加过却因为点进去结果狂掉\(rating\)-- \(A\) 集合 如果我们记 \[f_k=\sum_{i=1}^nT^i{n-i\choose k}\] 那么答案显然就是\(f_{k ...

  6. 「NOWCODER」CSP-S模拟赛第3场

    「NOWCODER」CSP模拟赛第3场 T1 货物收集 题目 考场思路即正解 T2 货物分组 题目 考场思路 题解 60pts 算法:一维 DP 100pts 算法:一维 DP ?线段树 + 单调栈 ...

  7. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  8. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  9. NOI.AC NOIP模拟赛 第四场 补记

    NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...

随机推荐

  1. TensorFlow使用记录 (一): 基本概念

    基本使用 使用graph来表示计算任务 在被称之为Session的上下文中执行graph 使用tensor表示数据 通过Variable维护状态 使用feed和fetch可以为任意的操作(op)赋值或 ...

  2. Mysql cluster管理节点配置文件详解

    一.定义MySQL Cluster的TCP/IP连接TCP/IP是MySQL集群用于建立连接的默认传输协议,正常情况下不需要定义连接.可使用“[TCP DEFAULT]”或“[TCP]”进行定义. 1 ...

  3. task.delay 和 thread.sleep

    1.Thread.Sleep 是同步延迟. Task.Delay异步延迟. 2.Thread.Sleep 会阻塞线程,Task.Delay不会. 3.Thread.Sleep不能取消,Task.Del ...

  4. Vue一个案例引发的动态组件与全局事件绑定总结

    最近在自学 Vue 也了解了一些基本用法,也记录了一些笔记有兴趣的朋友可以去查看我的其他文章,技术这东西真的不能光靠看,看是没有的,你必须要动手实践,只有在实战项目中才能发现问题,才能发现我们没有掌握 ...

  5. is == 编码与解码

    is 和 ==  主要是数字和字符串的比较 1 区别: ==比较的是两边的值     is比较的是两边值的id    id获取的方法 id() 2 小数据池: -5~256 3 字符串中特殊字符有id ...

  6. leetcode227 基本计算器

    1先利用符号栈转化为逆波兰表达式,并添加‘,’作为一个数字的结尾: 2然后利用数字栈计算逆波兰表达式的值: class Solution { public: int calculate(string ...

  7. 浏览器端-W3School-JavaScript-HTML DOM:HTML DOM Document 对象

    ylbtech-浏览器端-W3School-JavaScript-HTML DOM:HTML DOM Document 对象 1.返回顶部 1. HTML DOM Document 对象 Docume ...

  8. Windows 10下怎么远程连接 Ubuntu 16.0.4(小白级教程)

    前言: 公司因为用Ruby做开发,所有适用了Ubuntu系统,但是自己笔记本是W10,又不想装双系统,搭建开发环境,便想到倒不如自己远程操控公司电脑,这样在家的时候也可以处理一些问题.故此便有了下面的 ...

  9. emqtt 系统主题

    $SYS-系统主题 EMQ 消息服务器周期性发布自身运行状态.MQTT 协议统计.客户端上下线状态到 $SYS/ 开头系统主题. $SYS 主题路径以 “$SYS/brokers/{node}/” 开 ...

  10. python接口测试之mock(三)

    前面介绍了moco的详细的使用,它主要是基于moco-runner-0.11.0-standalone.jar,通过编写json的文件来实现,mock翻译过来就是模拟的意思,也就是说,它是将测试对象所 ...