B. 游戏

大意: $n$堆石子, 第$i$堆初始$a_i$, 每次只能选一堆, 假设一堆个数$x$, 只能取$x$的约数, 求先手第一步必胜取法.

SG入门题, 预处理出所有$SG$值. 先手要必胜必须满足留给后手的异或值为0.

#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#include <bitset>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
#define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, P2 = 998244353, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
//head const int N = 1e5+10;
int n, a[N], sg[N], vis[N];
vector<int> fac[N]; void init() {
REP(i,1,N-1) for(int j=i;j<N;j+=i) fac[j].pb(i);
REP(i,1,N-1) {
for (int j:fac[i]) vis[sg[i-j]]=i;
REP(j,0,N-1) if (vis[j]!=i) {
sg[i] = j; break;
}
}
} int main() {
init();
scanf("%d", &n);
int s = 0;
REP(i,1,n) {
scanf("%d", a+i);
s ^= sg[a[i]];
}
if (!s) return puts("0"),0;
int ans = 0;
REP(i,1,n) {
for (int x:fac[a[i]]) {
if (!(s^sg[a[i]]^sg[a[i]-x])) ++ans;
}
}
printf("%d\n", ans);
}

C.收益

大意: 要融资$L$元$n$个人, 融资成功收益$M$, 第$i$个客户有$p_i$概率出钱$m_i$元, 若融资成功要付$m_ir_i$元, 求最后期望收益.

DP求出最终得到$x$元的概率及期望花费, 然后统计答案.

#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#include <bitset>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
#define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, P2 = 998244353, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
//head const int N = 111;
int n, L, M;
int m[N], r[N], p[N];
int f[2][500100], g[2][500100]; int main() {
scanf("%d%d%d", &n, &L, &M);
int sum = 0, inv100 = inv(100);
REP(i,1,n) {
scanf("%d%d%d",m+i,r+i,p+i);
sum += m[i];
r[i] = (ll)m[i]*r[i]%P*inv100%P;
p[i] = (ll)p[i]*inv100%P;
}
int cur = 0;
f[cur][0] = 1;
REP(i,1,n) {
cur ^= 1;
REP(j,0,sum) {
int nxt = j-m[i]>=0?j-m[i]:sum+1;
f[cur][j] = ((ll)f[!cur][nxt]*p[i]+(ll)f[!cur][j]*(1-p[i]))%P;
g[cur][j] = (((ll)g[!cur][nxt]+(ll)r[i]*f[!cur][nxt])%P*p[i]+(ll)g[!cur][j]*(1-p[i]))%P;
}
}
int ans = 0;
REP(i,L,sum) ans = (ans+(ll)f[cur][i]*M-g[cur][i])%P;
if (ans<0) ans += P;
printf("%d\n", ans);
}

D.漂亮的公园

给定树, 点$i$颜色为$c[i]$, 每次询问所有颜色为$x$的点到颜色为$y$的点的最大距离.

结论: 对于树上点集$S$, $S$内距离最远的两点为$x,y$, 则其他点$u$到点集$S$的最远距离必然是$u$到$x$或$u$到$y$.

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#define REP(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int N = 1e5+10;
int n, q, c[N], sz[N], dep[N];
int fa[N], son[N], top[N];
int f[N][2];
vector<int> g[N];
int b[N]; void dfs(int x, int d, int f) {
sz[x]=1,fa[x]=f,dep[x]=d;
for (int y:g[x]) if (y!=f) {
dfs(y,d+1,x),sz[x]+=sz[y];
if (sz[y]>sz[son[x]]) son[x]=y;
}
}
void dfs(int x, int tf) {
top[x]=tf;
if (son[x]) dfs(son[x],tf);
for (int y:g[x]) if (!top[y]) dfs(y,y);
}
int lca(int x, int y) {
while (top[x]!=top[y]) {
if (dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int dis(int x, int y) {
if (!x||!y) return 0;
return dep[x]+dep[y]-2*dep[lca(x,y)];
} void upd(int x) {
int &A = f[c[x]][0], &B = f[c[x]][1];
if (!A) A = x;
else if (!B) B = x;
else {
int d1 = dis(A,B), d2 = dis(A,x), d3 = dis(B,x);
if (d2>d1&&d2>d3) {
if (d2>d3) B = x;
else A = x;
}
else if (d3>d1) A = x;
}
} int main() {
scanf("%d%d", &n, &q);
REP(i,1,n) scanf("%d",c+i),b[i]=c[i];
sort(b+1,b+1+n),*b=unique(b+1,b+1+n)-b-1;
REP(i,1,n) c[i]=lower_bound(b+1,b+1+*b,c[i])-b;
REP(i,2,n) {
int u, v;
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,0,0),dfs(1,1);
REP(i,1,n) upd(i);
while (q--) {
int x, y;
scanf("%d%d", &x, &y);
int xx=lower_bound(b+1,b+1+*b,x)-b;
int yy=lower_bound(b+1,b+1+*b,y)-b;
if (b[xx]!=x||b[yy]!=y) {
puts("0"); continue;
}
x = xx, y = yy;
int ans = 0;
REP(i,0,1) REP(j,0,1) ans = max(ans, dis(f[x][i],f[y][j]));
printf("%d\n", ans);
}
}

E. 排序

大意: 初始有一个长为$2n$的排列, 随机打乱后, 将奇数位升序排列, 求期望逆序对. $n\le 5e7$

打个表发现答案是$\frac{7n^2-n}{12}$, 官方题解如下

F 生成树计数 留坑

Wannafly挑战赛23的更多相关文章

  1. Wannafly挑战赛23 T2游戏 SG函数

    哎,被卡科技了,想了三个小时,最后还是大佬给我说是\(SG\)函数. \(SG\)函数,用起来很简单,证明呢?(不可能的,这辈子都是不可能的) \(SG\)定理 游戏的\(SG\)函数就是各个子游戏的 ...

  2. 题解——牛客网Wannafly挑战赛23 B-游戏 (SG函数)

    前言 比赛的时候没学过SG函数的蒟蒻以为是道结论题,但是不是QwQ 和dummyummy巨佬一起推了快三个小时的规律 最后去问了真正的巨佬__stdcall __stdcall面带微笑的告诉我们,这是 ...

  3. Wannafly挑战赛23 A 字符串

    题目描述 小N现在有一个字符串S.他把这这个字符串的所有子串都挑了出来.一个S的子串T是合法的,当且仅当T中包含了所有的小写字母.小N希望知道所有的合法的S的子串中,长度最短是多少. 输入描述: 一行 ...

  4. 牛客Wannafly挑战赛23 B.游戏

    游戏 题目描述 小N和小O在玩游戏.他们面前放了n堆石子,第i堆石子一开始有ci颗石头.他们轮流从某堆石子中取石子,不能不取.最后无法操作的人就输了这个游戏.但他们觉得这样玩太无聊了,更新了一下规则. ...

  5. 【牛客Wannafly挑战赛23】F 计数

    题目链接 题意 给定一张边带权的无向图,求生成树的权值和是 k 的倍数的生成树个数模 p 的值. \(n\leq 100,k\leq 100,p\mod k=1\) Sol 看见整除然后 \(p\mo ...

  6. hihoCoder挑战赛23

    hihoCoder挑战赛23 A.Emulator 题意 给一张图,有\(N(N \le 300)\)个点, 给出任意两点之间的最短路. 求最多可以去掉多少条边,使得任意两点的最短路长度不变. 思路 ...

  7. Wannafly挑战赛25游记

    Wannafly挑战赛25游记 A - 因子 题目大意: 令\(x=n!(n\le10^{12})\),给定一大于\(1\)的正整数\(p(p\le10000)\)求一个\(k\)使得\(p^k|x\ ...

  8. Wannafly挑战赛27

    Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...

  9. Wannafly 挑战赛 19 参考题解

    这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...

随机推荐

  1. asyncio之异步上下文管理器

    异步上下文管理器 前面文章我们提到了上下文管理器,但是这个上下文管理器只适用于同步代码,不能用于异步代码(async def形式),不过不用担心今天我们就来讨论在异步中如何使用上下文管理器. 特别提醒 ...

  2. Python generator 类型

    场景: 使用gurobi求解优化问题时,遇到quicksum()函数用法如下: quicksum(mu[i] for i in range(n)) 读着很流畅而且好像并没什么问题欸,但 mu[i] f ...

  3. Qt 线程基础(QThread、QtConcurrent等) 2

    使用线程 基本上有种使用线程的场合: 通过利用处理器的多个核使处理速度更快. 为保持GUI线程或其他高实时性线程的响应,将耗时的操作或阻塞的调用移到其他线程. 何时使用其他技术替代线程 开发人员使用线 ...

  4. [Tex学习笔记]让项目编号从4开始

    微信扫描如上二维码关注跟锦数学微信公众账号. 详情请见那里.

  5. Linux ldd -- 查看可执行文件所依赖的动态链接库

    我们知道“ldd”这个命令主要是被程序员或是管理员用来查看可执行文件所依赖的动态链接库的.是的,这就是这个命令的用处.可是,这个命令比你想像的要危险得多,也许很多黑客通过ldd的安全问题来攻击你的服务 ...

  6. SQL-W3School-高级:SQL NULL 函数

    ylbtech-SQL-W3School-高级:SQL NULL 函数 1.返回顶部 1. SQL ISNULL().NVL().IFNULL() 和 COALESCE() 函数 请看下面的 &quo ...

  7. python 获取昨天的日期

    from datetime import timedelta, datetime yesterday = datetime.today()+timedelta(-1) yesterday_format ...

  8. C++ STL swap_range

    #include <iostream>#include <vector>#include <deque>#include <algorithm> usi ...

  9. java调用js脚本

    有些情况下,需要java去调用js,groovy等脚本语言,传入参数获取脚本运行的结果. js脚本例子: function add(a,b){ return a + b + number; } jav ...

  10. JAVA 基础编程练习题24 【程序 24 根据输入求输出】

    24 [程序 24 根据输入求输出] 题目:给一个不多于 5 位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. package cskaoyan; public class cskaoya ...