0+0+20=20,不给大样例,小数据又水,还没有题解的垃圾题。

A 题

问题描述:

long long ago, Lxhgww 统治的国家里有 n 个城市,其中某一个城市是 capital (首都),这 n 个城市构成以 capital 为根的有向树。

Lxhgww 会通过发送指令去派一些士兵去保卫这些城市。Lxhgww 发出的指令格式为 x,k,表示向 x 结点派送 k 个士兵,向 x 的子节点派送 k + 1 个士兵,向 x 的子节点的子节点派送 k + 2 个士兵,以此类推。

现在考古学家通过考古,发现了 Lxhgww 的国家的部分信息。考古学家只得到了这棵树的 n - 1 条边,但并不知道这 n - 1 条边的方向,也不知道哪个城市才是 capital。考古学家也得到了所有 Lxhgww 发出的指令。

考古学家们知道 Lxhgww 是一个非常聪明的人,所以他们认为:以 capital 为根,这些指令所派送的士兵总数一定是最少的。

现在考古学家想让你告诉他们,这些指令所派送的士兵总数的最小值是多少,以及哪些点有可能是 capital。

输入:

第一行读入两个整数 n,m,分别表示城市的个数以及指令的数量。

接下来 n - 1 行,每行读入两个数 ai, bi,表示 ai 与 bi 之间有一条边。(注意边是没有方向的)

接下来 m 行,每行读入两个数 x, k。

输出:

第一行输出一个整数,表示完成这些指令所需的最小值。 第二行输出若干个

数,表示可能是 capital 的节点,这些数按照从小到大的顺序输出。

样例输入:

5 2

1 5

1 3

1 2

2 4

1 1

3 1

样例输出:

6

2 4

数据范围:

对于 10%的数据,1 <= n, m <= 300

对于 40%的数据,1 <= n, m <= 5000

对于 100%的数据,1 <= n, m <= 500000, 0 <= k <= 1000, 1 <= ai, bi, x <= n

题解

将贡献拆分,就是\(k\times siz_x+\sum_{y \in subtree_x} dep_y-depx\)。

注意到根从父亲变到自己的变动量只有父亲和自己,然后换根大力维护即可。时间复杂度\(O(n)\)。

然后我没有注意到多次加到同一个点上时\(\sum dep\)要翻倍,也没有注意到\(k=0\)的情况。此题爆0。

#include<bits/stdc++.h>
using namespace std;
template<class T> T read(){
T x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x;
}
template<class T> T read(T&x){
return x=read<T>();
}
#define co const
#define il inline
#define int long long co int N=500000+10;
int n,m,val[N],cnt[N]; // edit 1:cnt
vector<int> to[N]; int siz[N],dep[N],sd[N],sv[N]; void dfs1(int x,int fa){
siz[x]=1,sd[x]=dep[x];
for(int i=0;i<(int)to[x].size();++i){
int y=to[x][i];
if(y==fa) continue;
dep[y]=dep[x]+1;
dfs1(y,x);
siz[x]+=siz[y],sd[x]+=sd[y],sv[x]+=sv[y];
}
if(cnt[x]) sv[x]+=val[x]*siz[x]+cnt[x]*(sd[x]-dep[x]*siz[x]); // edit 2:k=0
} int ans=1e18;
vector<int> sol; void dfs2(int x,int fa,int sumd,int sumv){
if(fa){
if(cnt[x]) sumv-=val[x]*siz[x]+cnt[x]*(sd[x]-dep[x]*siz[x]);
if(cnt[fa]) sumv-=val[fa]*n+cnt[fa]*sumd;
sumd-=sd[x]-dep[x]*siz[x]+siz[x];
sumd+=n-siz[x]+sd[x]-dep[x]*siz[x];
if(cnt[x]) sumv+=val[x]*n+cnt[x]*sumd;
if(cnt[fa]) sumv+=val[fa]*(n-siz[x])+cnt[fa]*(sumd-(sd[x]-dep[x]*siz[x])-(n-siz[x]));
}
if(sumv<ans) ans=sumv,sol.assign(1,x);
else if(sumv==ans) sol.push_back(x);
for(int i=0;i<(int)to[x].size();++i){
int y=to[x][i];
if(y==fa) continue;
dfs2(y,x,sumd,sumv);
}
} signed main(){
freopen("A.in","r",stdin),freopen("A.out","w",stdout);
read(n),read(m);
for(int i=1;i<n;++i){
int x=read<int>(),y=read<int>();
to[x].push_back(y),to[y].push_back(x);
}
while(m--){
int x=read<int>();
val[x]+=read<int>(),++cnt[x];
}
dfs1(1,0);
dfs2(1,0,sd[1],sv[1]);
printf("%lld\n",ans);
sort(sol.begin(),sol.end());
for(int i=0;i<(int)sol.size();++i) printf("%lld ",sol[i]);
return 0;
}

B 题

问题描述:

Falsy 是一个可爱的女孩,她十分喜欢数字,她的梦想就是成为一名数学老师。有一天当她在把玩她的数字的时候,她不小心碰到了一个变量 x。初始时 x 的值为 x0。她发现每触碰一次这个变量,x 的值就会变成(kx + b) mod P。现在 Falsy 想让这个变量的值变回初始的样子,请你告诉她最少需要触碰多少次这个变量,能使它的值从 x0 又变回 x0。

输入:

第一行包含一个整数 T,表示测试数据组数。

每次测试数据包含四个整数:k,b,x0,P。

输出:

对于每组测试数据输出一行包含一个整数,表示对应的答案,若无解则输出-1。

样例输入:

2

4 7 1 13

11 4 2 12

样例输出:

6

1

数据范围:

对于 20%的数据,1 <= P <= 106,1 <= T <= 10。

对于 100%的数据,0 <= k,b,x0 < P,1 <= P <= 109 + 9,1 <= T <= 100。

题解

大力推式子,发现变动\(n\)次的结果是:

\[k^n x+b\sum_{i=0}^{n-1}k^i=k^nx+b\frac{k^n-1}{k-1}
\]

开始解方程

\[k^nx+b\frac{k^n-1}{k-1}=x \mod P\\
(k^n-1)(x+\frac{b}{k-1})=0 \mod P
\]

我一开始直接通分化简得到

\[(k^n-1)[(k-1)x+b]=0 \mod P
\]

谁知道这样做是错的。因为\(k-1\)不一定有逆元,所以从前一个推到这个没问题,但推回去就是错的。

王贝贝写出了正确的方程,必须要考虑进去\(P\)的变动。

\[(k^n-1)(x+\frac{b}{k-1})+mP=0\\
(k^n-1)[(k-1)x+b]+m(k-1)P=0
\]

以下用\([]\)代替\([(k-1)x+b]\)。这时如果将\(k^n-1\)和\(m\)看成未知数去解方程

\[k^n-1=0 \mod \frac{(k-1)P}{\gcd([],(k-1)P)}
\]

这样做的答案是正确的,但是时间复杂度\(O(T P)\),和暴力没有多大区别。

令\(Q=\frac{P}{\gcd([],P)}\),标程通过解方程

\[(k^n-1)\frac{[]}{\gcd([],P)}=0 \mod Q\\
k^n=1 \mod Q
\]

然后通过矩阵求逆???构造出了满足

\[(k^n-1)\frac{[]}{\gcd([],P)}+m(k-1)Q=0
\]

的答案。

\[\begin{bmatrix}
b & x
\end{bmatrix}
\cdot
\begin{bmatrix}
1 & 1\\
0 & k
\end{bmatrix}
\]

std的代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <bitset>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define FI first
#define SE second
using namespace std;
typedef long long LL; inline int phi(int n) {
int ret = n, a = n;
for(int i = 2; i * i <= a; ++i) {
if(a % i) continue;
ret = ret / i * (i - 1);
while(a % i == 0) a /= i;
}
if(a > 1) ret = ret / a * (a - 1);
return ret;
} int pow_mod(LL a, int p, int mod) {
LL c = 1;
while(p) {
if(p & 1) c = c * a % mod;
p >>= 1;
a = a * a % mod;
}
return c;
} void mul(int a[][2], int b[][2], int mod) {
int c[2][2] = { {0, 0}, {0, 0} };
for(int i = 0; i < 2; ++i) {
for(int j = 0; j < 2; ++j) {
for(int k = 0; k < 2; ++k) {
c[i][j] = (c[i][j] + (LL)a[i][k] * b[k][j]) % mod;
}
}
}
memcpy(a, c, sizeof(c));
} int k, b, x, p;
int cal(int n, int mod) {
if(n == 0) return 1;
int A[2][2] = { {1, 1}, {0, k} };
int C[2][2] = { {1, 0}, {0, 1} };
while(n) {
if(n & 1) mul(C, A, mod);
n >>= 1;
mul(A, A, mod);
}
return (1LL * k * C[0][1] + 1) % mod;
} int main() {
freopen("B.in", "r", stdin);
freopen("B.out", "w", stdout);
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d%d", &k, &b, &x, &p);
if(k == 0) {
puts(x == b ? "1" : "-1");
continue;
}
if(k == 1) {
if(b == 0) {
puts("1");
continue;
}
printf("%d\n", p / __gcd(p, b));
continue;
}
int q = p / __gcd((LL)p, (LL)(k - 1) * x + b);
if(q == 1) {
puts("1");
continue;
}
if(__gcd(k, q) != 1) {
puts("-1");
continue;
}
int f = phi(q), mi = f;
for(int i = 1; i * i <= f; ++i) {
if(f % i) continue;
if(pow_mod(k, i, q) == 1) {
mi = i; break;
}
if(pow_mod(k, f / i, q) == 1) mi = f / i;
}
int ans = cal(mi - 1, q);
ans = q / __gcd(ans, q) * mi;
printf("%d\n", ans);
}
fclose(stdin);
fclose(stdout);
return 0;
}

C 题

问题描述:

Fang Fang 是一个非常讨厌二进制数的人,尤其是 8 位的二进制数。某一天她遇到了 n 个 8 位二进制数,她决定要把它们全部消灭掉。Fang Fang 手上有 m 个武器。其中某些武器可以把所有 8 位二进制表示包含某个特定前缀的数全部消灭;某些武器可以把所有 8 位二进制表示包含某个特定后缀的数全部消灭。但是每使用一个武器都会消耗 Fang Fang 一定的 IQ值,现在你需要帮助她用最少的 IQ 值把所有数字消灭。

输入:

第一行读入两个整数 n,m,分别表示数字个数以及武器个数。

第二行包含 n 个整数 ai。

接下来 m 行,每行表示一个武器:

P s w:你可以消灭所有 8 位二进制表示中包含前缀 s 的数,消耗 w 点 IQ。

S s w:你可以消灭所有 8 位二进制表示中包含后缀 s 的数,消耗 w 点 IQ。

输出:

输出一行包含一个整数,表示对应的答案。若无法消灭所有的数,输出-1。

样例输入:

8 7

0 1 2 3 4 5 6 7

P 000001 1

P 0000000 1

S 10 1

S 11 1

S 00 1

S 01 1

P 0000001 3

样例输出:

4

数据范围:

对于 30%的数据,1 <= n <= 20,1 <= m <= 50;

对于 100%的数据,1 <= n <= 256,1 <= m <= 500,0 <= ai <= 255,1 <= w <= 1000,s 是一个 01 串,1 <= |s| <= 8。

题解

建出前缀和后缀的Trie树,考虑最小割模型。

把需要消灭的点用 INF 边连起来。

有 P 就在 P 对应前缀Trie树上把对应点父亲到自己的边的流量设为权值,没有 P 就把流量设成 INF。S 的做法同理。

然后跑最小割就行了。算是一道网络流好题。

test20190818 NOIP2019 模拟赛的更多相关文章

  1. test20190827 NOIP2019 模拟赛

    100+100+50=250.最后那道期望题需要用另外的方式统计. 精灵加护 ljss 被 M 个敌人打倒在地上啦!每个敌人有一个威力值 bi.但是他手中还拥有 N 把武器!每把武器有一个威力值 ai ...

  2. test20190826 NOIP2019 模拟赛

    100+100+40=240.我觉得如果没做过第三题考场上却能想出来的都是神仙. 基因突变 [问题描述] 邪恶的 707 刚刚从白垩纪穿越回来,心中产生了一个念头:我要统治人类! 但是统治人类是很庞大 ...

  3. test20190816 NOIP2019 模拟赛

    100+100+20=220,T3吐槽:整个考室没有一个人正确地理解了题意. 树上路径(phantasm) Akari 的学校的校门前生长着一排 n 棵树,从西向东依次编号为 1 ∼ n.相邻两棵树间 ...

  4. 题解 noip2019模拟赛Day1T3

    题面 运河计划 问题描述 水运在人类的交通运输史中一直扮演着重要的角色.借助河流.的便利,人们得以把大量的货物输送到天南海北不仅仅是自然界现成的河流,人工开凿的运河(如苏伊士运河.巴拿马运河.我国的京 ...

  5. [NOIP2019模拟赛]LuoguP4261白金元首与克劳德斯

    题目描述 给出坐标系中n个矩形,类型1的矩形每单位时间向x轴正方向移动1个单位,类型2的矩形向y轴正方向,初始矩形不重叠,一个点被矩形覆盖当且仅当它在矩形内部(不含边界),求$(-\infty ,+\ ...

  6. [NOIP2019模拟赛][AT2381] Nuske vs Phantom Thnook

    题目链接 评测姬好快啊(港记号?)暴力40pts变成60pts 因为题目说了保证蓝色点两两之间只有一条路径,所以肯定组成了一棵树,而对于每次询问的x1,y1,x2,y2的子矩阵中就存在着一个森林 不难 ...

  7. [NOIP2019模拟赛]HC1147 时空阵

    题目描述: 幽香这几天学习了魔法,准备建造一个大型的时空传送阵. 幽香现在可以在幻想乡的n个地点建造一些传送门,如果她建造了从地点a与地点b之间的传送门,那么从a到b和从b到a都只需要单位1的时间. ...

  8. [NOIP2019模拟赛]数数(gcd)

    题目大意: 求l~r中有多少数与x互质,带单点修改 分析: 两个30的部分分很好打: ·n<=1000暴力O(nq)就好了 ·$a_i<=100$用树状数组维护每个x的前缀和就好了 100 ...

  9. [NOIP2019模拟赛]序列(Sequence)

    题目大意 有一个序列$A_i$ • 对于 i ≥ 1,如果有$ A_i > 0.A_{i+1}> 0$ 且存在 $A_{i+2}$,那么法老可以令$ Ai$ 和 $A_{i+1}$ 减一, ...

随机推荐

  1. 【转】Fuel-Openstack的搭建(一)

    原文链接:https://blog.csdn.net/qq_35180983/article/details/82181496 2.1安装前的准备操作: 首先,我们需要准备以下操作: 2.1.1 下载 ...

  2. java并发-ReentrantLock的lock和lockInterruptibly的区别

    ReentrantLock的加锁方法Lock()提供了无条件地轮询获取锁的方式,lockInterruptibly()提供了可中断的锁获取方式.这两个方法的区别在哪里呢?通过分析源码可以知道lock方 ...

  3. python 之 网络编程(基于TCP协议的套接字通信操作)

    第八章网络编程 8.1 基于TCP协议的套接字通信 服务端套接字函数 s.bind() 绑定(主机,端口号)到套接字 s.listen() 开始TCP监听 s.accept() 被动接受TCP客户的连 ...

  4. UiPath-level3-test1 and test2 答案

    需要的请联系QQ 1257123976   5-10元一份,必过

  5. day38——线程queue、事件event、协程

    day38 线程queue 多线程抢占资源 只能让其串行--用到互斥锁 线程queue 队列--先进先出(FIFO) import queue q = queue.Queue(3) q.put(1) ...

  6. Loader ,URLLoader ,URLStream的区别

    AS3代码   (1)  Loader              Loader 类可用于加载 SWF 文件或图像(JPG.PNG 或 GIF)文件. 使用 load() 方法来启动加载. 被加载的显示 ...

  7. Exception: HTTP 599: SSL certificate problem: unable to get local issuer certificate 解决办法

    使用Pyspider中报此错误. 错误原因: 这个错误会发生在请求 https 开头的网址,SSL 验证错误,证书有误. 解决方法: 使用self.crawl(url, callback=self.i ...

  8. java之servlet之文件下载

    1.在页面中,可以直接通过超链接来下载: a) 如果浏览器能够打开该文件,那么直接在浏览器中显示---不是想要的效果 b) 任何人都能下载,不能进行权限控制 2.通过servlet来进行下载,在ser ...

  9. 记一次在 Get 请求参数为 Null 值的折腾

    先说主要原因,是因为一个 NgZerro 的 Select 组件,需要显示 placeHolder 文字,初始值为 null,然后直接绑定到查询参数中,传输到后端导致 BadRequest,参数解析失 ...

  10. “SQL Server does not exist or access denied.”

    Have resolved the problem, the Port was different and so the Connection String now reads: <connec ...