NOIP2018 - 一些板子
好多东西都不熟练……
数论
数论分块「bzoj2956: 模积和」
10.28.2018
#include<bits/stdc++.h>
typedef long long ll;
const int MO = ;
const int inv6 = ; ll n,m,ans,del; inline void Add(ll &x, ll y){x = ((x+y)%MO+MO)%MO;}
ll sum(ll x){return x*(x+)%MO*(*x+)%MO*inv6%MO;}
ll calc(ll x)
{
ll ret = ;
for (ll i=, j=; i<=x; i=j+)
{
j = x/(x/i);
Add(ret, 1ll*(x/i)*(i+j)*(j-i+)/%MO);
}
return ((x%MO*x%MO-ret)+MO)%MO;
}
int main()
{
scanf("%lld%lld",&n,&m);
if (n > m) std::swap(n, m);
ans = calc(n)*calc(m)%MO;
del = n*m%MO*n%MO;
for (ll i=, j=; i<=n; i=j+)
{
j = std::min(n/(n/i), m/(m/i));
ll s1 = (sum(j)-sum(i-))*(n/i)%MO*(m/i)%MO;
ll s2 = (n*(m/i)%MO+m*(n/i)%MO)%MO*((i+j)*(j-i+)/%MO);
Add(del, (s1-s2)%MO);
}
Add(ans, -del);
printf("%lld\n",ans);
return ;
}
图论
点-树链剖分「1036: [ZJOI2008]树的统计Count」
10.24.2018
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ;
const int INF = 0x3f3f3f3f; struct node
{
int tot,fa,son,top;
}a[maxn];
int n,m;
char opt[];
int f[maxn<<][];
int chTot,chain[maxn],cnVal[maxn],d[maxn],dep[maxn];
int edgeTot,head[maxn],nxt[maxm],edges[maxm]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v)
{
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void pushup(int rt)
{
f[rt][] = std::max(f[rt<<][], f[rt<<|][]);
f[rt][] = f[rt<<][]+f[rt<<|][];
}
void build(int rt, int l, int r)
{
f[rt][] = -INF;
if (l==r){
f[rt][] = f[rt][] = cnVal[l];
return;
}
int mid = (l+r)>>;
build(rt<<, l, mid), build(rt<<|, mid+, r);
pushup(rt);
}
void dfs1(int x, int fa)
{
a[x].fa = fa, a[x].tot = ;
dep[x] = dep[fa]+, a[x].son = -;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (v!=fa){
dfs1(v, x);
a[x].tot += a[v].tot;
if (a[x].son==-||a[v].tot > a[a[x].son].tot)
a[x].son = v;
}
}
}
void dfs2(int x, int top)
{
chain[x] = ++chTot, cnVal[chTot] = d[x], a[x].top = top;
if (a[x].son==-) return;
dfs2(a[x].son, top);
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (v!=a[x].son&&v!=a[x].fa) dfs2(v, v);
}
}
void modify(int rt, int l, int r, int pos, int c)
{
if (l==r){
f[rt][] = f[rt][] = c;
return;
}
int mid = (l+r)>>;
if (pos <= mid) modify(rt<<, l, mid, pos, c);
else modify(rt<<|, mid+, r, pos, c);
pushup(rt);
}
int queryMx(int rt, int L, int R, int l, int r)
{
if (L <= l&&r <= R) return f[rt][];
int mid = (l+r)>>, ret = -INF;
if (L <= mid) ret = queryMx(rt<<, L, R, l, mid);
if (R > mid) ret = std::max(ret, queryMx(rt<<|, L, R, mid+, r));
return ret;
}
int querySm(int rt, int L, int R, int l, int r)
{
if (L <= l&&r <= R) return f[rt][];
int mid = (l+r)>>, ret = ;
if (L <= mid) ret = querySm(rt<<, L, R, l, mid);
if (R > mid) ret += querySm(rt<<|, L, R, mid+, r);
return ret;
}
int queryChainMx(int x, int y)
{
int ret = -INF;
while (a[x].top!=a[y].top)
{
if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
ret = std::max(ret, queryMx(, chain[a[y].top], chain[y], , n));
y = a[a[y].top].fa;
}
if (dep[x] > dep[y]) std::swap(x, y);
ret = std::max(ret, queryMx(, chain[x], chain[y], , n));
return ret;
}
int queryChainSm(int x, int y)
{
int ret = ;
while (a[x].top!=a[y].top)
{
if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
ret += querySm(, chain[a[y].top], chain[y], , n);
y = a[a[y].top].fa;
}
if (dep[x] > dep[y]) std::swap(x, y);
ret += querySm(, chain[x], chain[y], , n);
return ret;
}
int main()
{
memset(head, -, sizeof head);
n = read();
for (int i=; i<n; i++) addedge(read(), read());
for (int i=; i<=n; i++) d[i] = read();
dfs1(, );
dfs2(, );
build(, , n);
m = read();
while (m--)
{
scanf("%s",opt);
int x = read(), y = read();
if (opt[]=='C') modify(, , n, chain[x], y);
else if (opt[]=='M')
printf("%d\n",queryChainMx(x, y));
else printf("%d\n",queryChainSm(x, y));
}
return ;
}
打挂地方已标注。
边-树链剖分「bzoj2238: Mst」
10.28
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ;
const int INF = 0x3f3f3f3f; struct Edge
{
int u,v,w,id;
bool vis;
Edge(int a=, int b=, int c=):u(a),v(b),w(c) {}
}ev[maxm],edges[maxm];
struct node
{
int tot,son,top,fa;
}a[maxn];
int n,m,q,cnt,ans;
int dep[maxn],fa[maxn],chain[maxn],chTot,f[maxn<<];
int edgeTot,head[maxn],nxt[maxm];
bool evis[maxm]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
bool cmp1(Edge a, Edge b)
{
return a.w < b.w;
}
bool cmp2(Edge a, Edge b)
{
return a.id < b.id;
}
int get(int x){return x==fa[x]?x:fa[x]=get(fa[x]);}
void addedge(int u, int v, int c)
{
ans += c, fa[fa[u]] = fa[v];
edges[++edgeTot] = Edge(u, v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = Edge(v, u, c), nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void dfs1(int x, int fa)
{
a[x].tot = , a[x].son = a[x].top = -;
a[x].fa = fa, dep[x] = dep[fa]+;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i].v;
if (v!=fa){
dfs1(v, x), a[x].tot += a[v].tot;
if (a[x].son==-||a[a[x].son].tot < a[v].tot) a[x].son = v;
}
}
}
void dfs2(int x, int top)
{
a[x].top = top, chain[x] = ++chTot;
if (a[x].son==-) return;
dfs2(a[x].son, top);
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i].v;
if (v!=a[x].son&&v!=a[x].fa) dfs2(v, v);
}
}
void build(int rt, int l, int r)
{
f[rt] = INF;
if (l==r) return;
int mid = (l+r)>>;
build(rt<<, l, mid), build(rt<<|, mid+, r);
}
void Min(int &x, int y){x = x>y?y:x;}
void pushdown(int rt)
{
Min(f[rt<<], f[rt]), Min(f[rt<<|], f[rt]);
}
void modify(int rt, int L, int R, int l, int r, int c)
{
if (L > R) return;
if (L <= l&&r <= R){
f[rt] = std::min(f[rt], c);
return;
}
int mid = (l+r)>>;
pushdown(rt);
if (L <= mid) modify(rt<<, L, R, l, mid, c);
if (R > mid) modify(rt<<|, L, R, mid+, r, c);
}
int query(int rt, int L, int R, int l, int r)
{
if (L > R) return INF;
if (L <= l&&r <= R) return f[rt];
int mid = (l+r)>>, ret = INF;
pushdown(rt);
if (L <= mid) Min(ret, query(rt<<, L, R, l, mid));
if (R > mid) Min(ret, query(rt<<|, L, R, mid+, r));
return ret;
}
void modifyChain(int x, int y, int c)
{
while (a[x].top!=a[y].top)
{
if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
modify(, chain[a[y].top], chain[y], , n, c);
y = a[a[y].top].fa;
}
if (dep[x] > dep[y]) std::swap(x, y);
modify(, chain[x]+, chain[y], , n, c);
}
int queryChain(int x, int y)
{
int ret = INF;
while (a[x].top!=a[y].top)
{
if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
Min(ret, query(, chain[a[y].top], chain[y], , n));
y = a[a[y].top].fa;
}
if (dep[x] > dep[y]) std::swap(x, y);
Min(ret, query(, chain[x]+, chain[y], , n));
return ret;
}
int main()
{
memset(head, -, sizeof head);
n = read(), m = read();
for (int i=; i<=n; i++) fa[i] = i;
for (int i=; i<=m; i++)
ev[i].u = read(), ev[i].v = read(), ev[i].w = read(), ev[i].id = i;
std::sort(ev+, ev+m+, cmp1);
for (int i=; i<=m; i++)
if (get(ev[i].u)!=get(ev[i].v)){
int u = ev[i].u, v = ev[i].v;
ev[i].vis = evis[ev[i].id] = , cnt++, addedge(u, v, ev[i].w);
if (cnt==n-) break;
}
if (cnt!=n-){
q = read();
while (q--) puts("Not connected");
return ;
}
dfs1(, );
dfs2(, );
build(, , n);
for (int i=m; i; i--)
if (!ev[i].vis) modifyChain(ev[i].u, ev[i].v, ev[i].w);
std::sort(ev+, ev+m+, cmp2);
for (q=read(); q; q--)
{
int cse = read();
if (!evis[cse]) printf("%d\n",ans);
else{
int cnt = queryChain(ev[cse].u, ev[cse].v);
if (cnt!=INF) printf("%d\n",ans-ev[cse].w+cnt);
else puts("Not connected");
}
}
return ;
}
evis开成maxn一发RE
SPFA负权环「bzoj1715: [Usaco2006 Dec]Wormholes 虫洞」
10.24.2018
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ; struct Edge
{
int y,val;
Edge(int a=, int b=):y(a),val(b) {}
}edges[maxm];
int T,n,m,w;
bool vis[maxn];
int dis[maxn],edgeTot,head[maxn],nxt[maxm]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v, int c)
{
edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
}
bool dfs(int x)
{
vis[x] = ;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i].y;
if (dis[v] > dis[x]+edges[i].val){
dis[v] = dis[x]+edges[i].val;
if (vis[v]||dfs(v)){
vis[x] = ;
return ;
}
}
}
vis[x] = ;
return ;
}
int main()
{
T = read();
while (T--)
{
memset(head, -, sizeof head);
memset(dis, , sizeof dis);
edgeTot = , n = read(), m = read(), w = read();
for (int i=; i<=m; i++)
{
int u = read(), v = read(), c = read();
addedge(u, v, c), addedge(v, u, c);
}
for (int i=; i<=w; i++)
{
int u = read(), v = read(), c = read();
addedge(u, v, -c);
}
bool fl = ;
for (int i=; i<=n; i++)
if (dfs(i)){
puts("YES"), fl = ;
break;
}
if (!fl) puts("NO");
}
return ;
}
差分约束「poj1201Intervals」
10.26.2018
这个和线性规划相比,要把式子全都化成三角形不等式的形式。
所以小于等于或者大于等于的两种情况自己注意。
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ; struct Edge
{
int y,val;
Edge(int a=, int b=):y(a),val(b) {}
}edges[maxm];
int n,mx;
bool stk[maxn];
std::queue<int> q;
int dis[maxn],vis[maxn];
int edgeTot,head[maxn],nxt[maxm]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v, int c)
{
edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
}
void spfa()
{
memset(dis, -0x3f3f3f3f, sizeof dis);
dis[] = , q.push();
while (q.size())
{
int tt = q.front();
q.pop(), stk[tt] = ;
for (int i=head[tt]; i!=-; i=nxt[i])
{
int v = edges[i].y, w = edges[i].val;
if (dis[v] < dis[tt]+w){
dis[v] = dis[tt]+w;
if (!stk[v]) stk[v] = , q.push(v);
}
}
}
}
int main()
{
memset(head, -, sizeof head);
n = read();
for (int i=; i<=n; i++)
{
int a = read()+, b = read()+, c = read();
mx = std::max(mx, b);
addedge(a-, b, c);
}
for (int i=; i<mx; i++) addedge(i, i+, ), addedge(i+, i, -);
spfa();
printf("%d\n",dis[mx]);
return ;
}
≥
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ; struct Edge
{
int y,val;
Edge(int a=, int b=):y(a),val(b) {}
}edges[maxm];
int n,mx;
bool stk[maxn];
std::queue<int> q;
int dis[maxn],vis[maxn];
int edgeTot,head[maxn],nxt[maxm]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v, int c)
{
edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
}
void spfa()
{
memset(dis, 0x3f3f3f3f, sizeof dis);
dis[mx] = , q.push(mx);
while (q.size())
{
int tt = q.front();
q.pop(), stk[tt] = ;
for (int i=head[tt]; i!=-; i=nxt[i])
{
int v = edges[i].y, w = edges[i].val;
if (dis[v] > dis[tt]+w){
dis[v] = dis[tt]+w;
if (!stk[v]) stk[v] = , q.push(v);
}
}
}
}
int main()
{
memset(head, -, sizeof head);
n = read();
for (int i=; i<=n; i++)
{
int a = read()+, b = read()+, c = read();
mx = std::max(mx, b);
addedge(b, a-, -c);
}
for (int i=; i<mx; i++) addedge(i, i+, ), addedge(i+, i, );
spfa();
printf("%d\n",-dis[]);
return ;
}
≤
点树上差分「bzoj4390: [Usaco2015 dec]Max Flow」
11.5.2018
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ;
const int maxLog = ; int n,m;
int f[maxn][maxLog],sum[maxn],ans;
int edgeTot,head[maxn],edges[maxm],nxt[maxm],dep[maxn]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v)
{
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void dfs(int x, int fa)
{
f[x][] = fa, dep[x] = dep[fa]+;
for (int i=head[x]; i!=-; i=nxt[i])
if (edges[i]!=fa) dfs(edges[i], x);
}
int lca(int u, int v)
{
if (dep[u] > dep[v]) std::swap(u, v);
for (int i=; i>=; i--)
if (dep[u] <= dep[v]-(<<i))
v = f[v][i];
if (u==v) return u;
for (int i=; i>=; i--)
if (f[u][i]!=f[v][i])
u = f[u][i], v = f[v][i];
return f[u][];
}
void fnd(int x)
{
for (int i=head[x]; i!=-; i=nxt[i])
if (edges[i]!=f[x][])
fnd(edges[i]), sum[x] += sum[edges[i]];
if (ans < sum[x]) ans = sum[x];
}
int main()
{
memset(head, -, sizeof head);
n = read(), m = read();
for (register int i=; i<n; i++) addedge(read(), read());
dfs(, );
for (register int j=; j<=; j++)
for (register int i=; i<=n; i++)
f[i][j] = f[f[i][j-]][j-];
for (register int i=; i<=m; i++)
{
register int u = read(), v = read(), ger = lca(u, v);
sum[u]++, sum[v]++, sum[ger]--, sum[f[ger][]]--;
}
fnd();
printf("%d\n",ans);
return ;
}
NOIP2018 - 一些板子的更多相关文章
- NOIP计划索引
药丸的节奏 亟待解决的问题 灵光一现的trick 2018上学期刷题记录 NOIP2018 - 暑期博客整理 NOIP2018 - 一些板子 NOIP2018 - 每日填坑
- NOIP2018赛前停课集训记——最后的刷板子计划
前言 再过两天就\(NOIP2018\)了. 于是,我决定不做其他题目,开始一心一意刷板子了. 这篇博客记录的就是我的刷板子计划. [洛谷3383][模板]线性筛素数 这种普及-的题目我还写挂了两次( ...
- NOIP2018 游记 QAQ
写在前面: 本人初三党.NOIP前两个月不好好停课搞信竞愣是要搞文化课.于是,期中考与NOIP一起凉凉[微笑] 本人写的第一篇NOIP游记,各位大佬们随便看一看就好 Day -n 初赛71,竟然跟wx ...
- NOIP2018题解
Preface 联赛结束后趁着自己还没有一下子把题目忘光,所以趁机改一下题目. 没有和游记一起写主要是怕篇幅太长不美观. 因此这里我们直接讲题目,关于NOIP2018的一些心得和有趣的事详见:NOIP ...
- NOIp2018停课刷题记录
Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...
- NOIP2018滚粗记
NOIP2018滚粗记 day 0 上午,说是可以休息,然后睡到快9点起来吃个早饭去了机房.刷了几个板子就十二点了 下午大概就是看别人总结,颓知乎,完全没心思写代码. 晚上不要求,然后在寝室颓了一下, ...
- 租酥雨的NOIP2018赛前日记
租酥雨的NOIP2018赛前日记 离\(\mbox{NOIP2018}\)只剩下不到一个月的时间辣! 想想自己再过一个月就要退役了,觉得有必要把这段时间的一些计划与安排记录下来. 就从国庆收假开始吧. ...
- 【日记】NOIP2018
day-2: 最后一次走出机房,刚下过几天的雨,感受到的是彻骨的寒意.下午离开教室,跟班主任请了接下来几天的假,班主任斜视了我一眼,哼了一声,确认了一下,不再理会我了.班里的同学或是忙着自己的作业,或 ...
- NOIP2018学军中学游记(11.09~11.11)
前言 这篇博客记录的是我在\(NOIP2018\)提高组比赛中的经历. 这一次的\(NOIP\)是在学军中学举办的, 莫名感到一阵慌张. 但愿能有一个好成绩,不然就要\(AFO\)了... ... 说 ...
随机推荐
- python 定位
#字符串定位 使用str.find() 其结果为如下: #列表中元素的定位 使用list.index() 其结果如下:
- dom4j解析简单的xml文件 解析元素并封装到对象
package cn.itcast.xml; import cn.itcast.domain.Book; import org.dom4j.Document; import org.dom4j.Doc ...
- 牛客小白月赛13 G(双向搜索)
AC通道 两边同步搜,一步里面A走一次B走两次,遇到对方走过的地方就得到了答案. #include <bits/stdc++.h> using namespace std; const i ...
- CSS——制作天天生鲜登陆页面
这个登陆页面主要是有一个form表单,其他的和首页差不多的. login.html: <!DOCTYPE html> <html lang="en"> &l ...
- 每天学点Linux命令之grep 和 wc命令 --- !管道命令!
Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expr ession Print,表示全局正则表 ...
- (转)io各层次性能汇总及运行速度对比
io各层次性能汇总:以上图片可以清晰的解释io的运行效率 守护进程:持续保持运行着的程序 进程:放在内存中运行的程序 程序:代码文件,php,java
- JDBC连接中Class.forName("")到底干了什么?
思考了一个问题,Class.forName("***");到底干了什么? 我们知道Class.forName( )静态方法的目的是为了动态加载类,但是一般来说,一个类forName ...
- Ubuntu 16.04 以太坊开发环境搭建
今天我们来一步一步从搭建以太坊智能合约开发环境. Ubuntu16.04 安装ubuntu16.04.下载链接 //先update一下(或者换国内源再update) sudo apt-get upda ...
- SLF4J user manual 专题
System Out and Err Redirected to SLF4J The sysout-over-slf4j module allows a user to redirect all ca ...
- 一道笔试题和UML思想 ~
一句软件工程界的名言,让我想起了一个和一道笔试题有关的故事.希望更多的人了解 UML 背后的思想比他的语法更重要,是笔者写作本文的一点小愿望. 一.从一句软件工程名言说起 对很多事情的处理上,东西方都 ...