牛客国庆集训派对Day5 Solution

时间:2021-04-30 20:27:40

A    璀璨光滑

留坑。

B    电音之王

蒙特马利大数乘模运算

 #include <bits/stdc++.h>
using namespace std; typedef long long ll;
typedef unsigned long long u64;
typedef __int128_t i128;
typedef __uint128_t u128; struct Mod64 {
Mod64() :n_() {}
Mod64(u64 n) :n_(init(n)) {}
static u64 init(u64 w) { return reduce(u128(w) * r2); }
static void set_mod(u64 m) {
mod = m; assert(mod & );
inv = m; for (int i = ; i < ; ++i) inv *= - inv * m;
r2 = -u128(m) % m;
}
static u64 reduce(u128 x) {
u64 y = u64(x >> ) - u64((u128(u64(x)*inv)*mod) >> );
return ll(y)< ? y + mod : y;
}
Mod64& operator += (Mod64 rhs) { n_ += rhs.n_ - mod; if (ll(n_)<) n_ += mod; return *this; }
Mod64 operator + (Mod64 rhs) const { return Mod64(*this) += rhs; }
Mod64& operator -= (Mod64 rhs) { n_ -= rhs.n_; if (ll(n_)<) n_ += mod; return *this; }
Mod64 operator - (Mod64 rhs) const { return Mod64(*this) -= rhs; }
Mod64& operator *= (Mod64 rhs) { n_ = reduce(u128(n_)*rhs.n_); return *this; }
Mod64 operator * (Mod64 rhs) const { return Mod64(*this) *= rhs; }
u64 get() const { return reduce(n_); }
static u64 mod, inv, r2;
u64 n_;
}; u64 Mod64::mod, Mod64::inv, Mod64::r2; int t, k;
u64 A0, A1, M0, M1, C, M; void Run()
{
scanf("%d", &t);
while (t--)
{
scanf("%llu%llu%llu%llu%llu%llu%d", &A0, &A1, &M0, &M1, &C, &M, &k);
Mod64::set_mod(M);
Mod64 a0(A0), a1(A1), m0(M0), m1(M1), c(C), ans(), a2();
ans *= a0; ans *= a1;
for (int i = ; i <= k; ++i)
{
a2 = a1;
a1 = m0 * a1 + m1 * a0 + c;
a0 = a2;
ans *= a1;
}
printf("%llu\n", ans.get());
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

C    萌新拆塔

留坑。

D    奇迹暖婊

留坑。

E    风花雪月

留坑。

F    双倍掉率

留坑。

G    贵族用户

枚举VIP等级,注意精度问题 不要用(1-p * 0.01) 用 (100 - p) * 1.0 / 100

 #include<bits/stdc++.h>

 using namespace std;

 const int maxn = 1e2 + ;

 int m, k;
int a[maxn], p[maxn], c[maxn], d[maxn]; int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &m, &k);
for(int i = ; i <= m; ++i) scanf("%d %d", a + i, p + i);
for(int i = ; i <= k; ++i) scanf("%d %d", c + i, d + i);
int ans = 0x3f3f3f3f;
//for(int i = 1; i <= k; ++i) ans += c[i] * d[i];
for(int i = ; i <= m; ++i)
{
int res = ;
for(int j = ; j <= k; ++j)
{
int tmp = (int)ceil(d[j] * (100.0 - p[i]) / 100.0);
res += tmp * c[j];
}
if(res < a[i]) res = a[i];
ans = min(ans, res);
}
ans = (int)ceil(ans * 0.1);
printf("%d\n", ans);
}
return ;
}

H    我不爱她

留坑。

I    人渣本愿

留坑。

J    友谊巨轮

用线段树维护每个人对其他人的聊天记录,然后取max上去,但是开1e5棵线段树肯定空间爆炸,考虑动态开点,每次最多开logn个结点

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define ll long long int t, n, m, k;
int root[N], res; struct SEG
{
#define M N * 35
int cnt, lson[M], rson[M];
struct node
{
int tm, pos;
ll Max;
bool operator < (const node &r) const
{
return Max == r.Max ? tm < r.tm : Max < r.Max;
}
}a[M]; void pushup(int id)
{
a[id] = max(a[lson[id]], a[rson[id]]);
} void update(int &root, int l, int r, ll val, int tm, int pos)
{
if (!root)
{
root = ++cnt;
lson[root] = rson[root] = ;
a[root].Max = a[root].tm = a[root].pos = ;
}
if (l == r)
{
a[root].Max += val;
a[root].tm = max(a[root].tm, tm);
a[root].pos = pos;
return;
}
int mid = (l + r) >> ;
if (pos <= mid) update(lson[root], l, mid, val, tm, pos);
else update(rson[root], mid + , r, val, tm, pos);
pushup(root);
}
}segtree; void Init()
{
segtree.cnt = ;
memset(root, , sizeof root);
res = ;
} struct OP
{
int a, b, c, tm;
void scan(int tm)
{
this->tm = tm;
scanf("%d%d%d", &a, &b, &c);
}
}op[N]; void update(int a, int b, int c, int tm)
{
int bef = segtree.a[root[a]].pos;
segtree.update(root[a], , n, c, tm, b);
int now = segtree.a[root[a]].pos;
if (bef == now) return;
if (bef)
{
if (segtree.a[root[bef]].pos == a) ++res;
else --res;
}
if (now)
{
if (segtree.a[root[now]].pos == a) --res;
else ++res;
} } void Run()
{
segtree.a[].tm = ; // 防止取max操作时误把空节点pushup上去
scanf("%d", &t);
while (t--)
{
Init();
scanf("%d%d%d", &n, &k, &m);
for (int i = ; i <= k; ++i)
{
op[i].scan(i);
update(op[i].a, op[i].b, op[i].c, i);
update(op[i].b, op[i].a, op[i].c, i);
if (i > m)
{
update(op[i - m].a, op[i - m].b, -op[i - m].c, i - m);
update(op[i - m].b, op[i - m].a, -op[i - m].c, i - m);
}
printf("%d\n", res);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

K    最后战役

留坑。

L    数论之神

两个规律,在代码中。

 #include <bits/stdc++.h>
using namespace std; #define ll long long int T;
ll n, k; int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%lld%lld", &n, &k);
ll t = (ll)sqrt(n);
// cout << t << endl;
ll num = t * (t + ) <= n ? * t : * t - ;
k = num - k + ;
ll K = k <= t ? k : n / (num - k + );
printf("%lld %lld\n", num, K);
}
return ;
}