标签:总结 Code NOIP Show int read freopen 第二阶段 getchar
联赛模拟测试37
阶段排名 27
A 简单题
-
考场上想出a+b+c是定值且q没啥用,但还是没找到规律
-
观察式子,将A和B加起来就可以把P消掉
-
然后每次变化就是A+B和C两个数中大的减小的,小的变两倍
-
如果C小,C变两倍,
-
如果C大,\(C=C-(A+B)=C-((A+B+C)-C)=2C-(A+B+C)\),C变两倍减去和,和是定值,答案就转换成\(C*2^k\mod (A+B+C)\)
Show Code
#include <cstdio>
int read(int x = 0, int f = 1, char c = getchar()) {
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >='0' && c <='9'; c = getchar())
x = x * 10 + c - '0';
return x * f;
}
int Pow(int a, int k, int M, int ans = 1) {
for (; k; k >>= 1, a = 1LL * a * a % M)
if (k & 1) ans = 1LL * ans * a % M;
return ans;
}
int main() {
freopen("easy.in", "r", stdin);
freopen("easy.out", "w", stdout);
int T = read();
while (T--) {
int x = read() + read(), y = read(), k = read();
x += y;
printf("%lld\n", 1LL * y * Pow(2, k, x) % x);
}
return 0;
}
B 斗地主
-
我记得学长讲过,但忘了怎么写了,本来想写60分二分图,然后懒得写,就写了个40分暴搜,有个地方写挂了就只剩20了
-
每张牌上正面的数向背面的数建双向边,一个联通块如果是树就会有一个点不能选,那么一个区间同时包含这个联通块的最大值和最小值,就不能组成
-
可以维护一个ans[i]表示从i开始最大能到几,双指针就可以O(n)预处理出这个数组,每次查询就可以做到O(1)了
Show Code
#include <cstdio>
const int N = 2e5 + 5;
int read(int x = 0, int f = 1, char c = getchar()) {
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >='0' && c <='9'; c = getchar())
x = x * 10 + c - '0';
return x * f;
}
int n, m, f[N], s[N], b[N], ans[N];
int Find(int x) {
return x == f[x] ? x : (f[x] = Find(f[x]));
}
int main() {
freopen("playingcard.in", "r", stdin);
freopen("playingcard.out", "w", stdout);
n = read(); m = read();
for (int i = 1; i <= n; ++i) f[i] = i;
while (m--) {
int x = Find(read()), y = Find(read());
s[x]++;
if (x == y) continue;
f[y] = x; s[x] += s[y];
}
for (int i = 1, j = 1; i <= n; ++i) {
for (int x; j <= n && b[x=Find(j)] < s[x]; ++j) b[x]++;
ans[i] = j - 1; b[Find(i)]--;
}
m = read();
while (m--) {
int x = read();
puts(read() <= ans[x] ? "Yes" : "No");
}
return 0;
}
C 变化的树
-
对于x子树上的点y,它增加的值就是w-k(dep[y]-dep[x]) = w+kdep[x]-kdep[y],
-
对于每个点维护w+kdep[x]的和sw[i]和k的和sk[i],查询的时候就是sw[x]-dep[x]sk[x]
-
那就拿一个支持区间加,单点查的数据结构,其实树状数组就可以,然而我考场写的大常数线段树
Show Code
#include <cstdio>
const int N = 3e5 + 5, M = 1e9 + 7;
int read(int x = 0, int f = 1, char c = getchar()) {
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return x * f;
}
struct Edge {
int next, t;
}e[N];
int head[N], edc;
void Add(int x, int y) {
e[++edc] = (Edge) {head[x], y};
head[x] = edc;
}
int n, dep[N], dfc, dfn[N], a[N], siz[N], tw[N], tk[N];
void Dfs(int x, int fa) {
siz[x] = 1;
dep[x] = dep[fa] + 1;
dfn[x] = ++dfc; a[dfc] = x;
for (int i = head[x]; i; i = e[i].next) {
int y = e[i].t;
Dfs(y, x);
siz[x] += siz[y];
}
}
void Add(int x, int w, int k) {
for (; x <= n; x += x & -x) {
if ((tw[x] += w) >= M) tw[x] -= M;
if ((tk[x] += k) >= M) tk[x] -= M;
}
}
int Ask(int x, bool g, int s = 0) {
for (; x; x -= x & -x)
if ((s += (g ? tw[x] : tk[x])) >= M) s -= M;
return s;
}
int main() {
freopen("change.in", "r", stdin);
freopen("change.out", "w", stdout);
n = read();
for (int i = 2; i <= n; ++i)
Add(read(), i);
Dfs(1, 0);
int m = read();
while (m--) {
int od = read(), x = read();
if (od == 1) {
int w = read(), k = read();
w = (w + 1LL * dep[x] * k) % M;
Add(dfn[x], w, k); Add(dfn[x] + siz[x], -w, -k);
}
else printf("%lld\n", (Ask(dfn[x], 1) - 1LL * dep[x] * Ask(dfn[x], 0) % M + M) % M);
}
return 0;
}
D 炼金术 (Unaccepted)
- 神仙题爆0
Show Code
标签:总结,Code,NOIP,Show,int,read,freopen,第二阶段,getchar 来源: https://www.cnblogs.com/shawk/p/14024277.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。