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. centos7 nginx 配置 ssl证书

    安装nginx 从阿里云服务器下载 nginx版本的ssl证书,防止再 /etc/nginx/ssl 下 停止 nginx 服务 systemctl stop nginx 修改配置文件 /etc/ng ...

  2. Google深度学习开源框架TenseorFlow安装

    Google近期发布了TensorFlow,考录到Google出品,必属精品,估计这玩意会火,不过火钳刘明已经来不及了 今天才想着安装来试试 TensorFlow官网:https://www.tens ...

  3. 02_四大组件之Activity

    四大组件之Activity 1. 理论概述 1.1 Activity的理解 Servlet的理解回顾 狭义 Servlet是一个interface,我们的Servlet类都必须是此接口的实现类 广义 ...

  4. 21 javaweb开发--bug调试技巧

    1.当修改代码后,测试时没有任何效果 解决方案:换个浏览器试试,可能是浏览器缓存的原因.

  5. css3 网页图片轮播的实现

    .lunbo{ height: 640px; width: 100%; background-position: -280px; margin-top: 103px; -webkit-animatio ...

  6. PAT(B) 1035 插入与归并(Java)

    题目链接:1035 插入与归并 (25 point(s)) 参考博客:PAT乙级--1035(插入排序和归并)java实现熊仙森 题目描述 根据维基百科的定义: 插入排序是迭代算法,逐一获得输入数据, ...

  7. 数列分段 II

    题目描述 思路 代码 #include <cstdio> int n, m, arr[100005], ans; int l, r, mid, inf = 0x7f3f3f3f; inli ...

  8. TypeScript之函数

    1.函数声明 与javascript一样,ts的函数声明也分为两种:函数声明,函数表达式 1)函数声明: function fn(age:number):string{ return `age is ...

  9. Luogu3214 HNOI2011 卡农 组合、DP

    传送门 火题qwq 我们需要求的是满足元素个数为\(M\).元素取值范围为\([1,2^n-1]\).元素异或和为\(0\)的集合的数量. 首先我们可以计算元素有序的方案数(即计算满足这些条件的序列的 ...

  10. Java隐式类型转换和强制类型转换

    一.强制类型转换 char 和 整型之间的类型转换 char a7 = 'a'; System.out.println(a7); System.out.println( (int)a7 ); Syst ...