Arithmetic
#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0'); x*=flg;
}
typedef long long LL;
#define pii pair<int,int>
#define fr first
#define sc second
#define mp make_pair
#define pb push_back
const int MAXN = 300005;
const int MAXV = 10000005;
int n, d, m, a[MAXN];
vector<pii>q[MAXN];
int q1[MAXN], top1, q2[MAXN], top2;
LL sum[MAXN<<2], lz[MAXN<<2], hsum[MAXN<<2], hlz[MAXN<<2], tag[MAXN<<2], len[MAXN<<2];
void build(int i, int l, int r) {
len[i] = r-l+1;
if(l == r) return;
int mid = (l + r) >> 1;
build(i<<1, l, mid);
build(i<<1|1, mid+1, r);
}
inline void giv3(int i, LL v) {
tag[i] += v; hsum[i] += v * len[i];
}
inline void giv2(int i, LL v) {
hlz[i] += v; hsum[i] += v * sum[i];
}
inline void giv1(int i, LL v) {
if(hlz[i]) tag[i] += -hlz[i]*v;
lz[i] += v; sum[i] += v*len[i];
}
inline void pd(int i) {
if(lz[i]) giv1(i<<1, lz[i]), giv1(i<<1|1, lz[i]), lz[i] = 0;
if(hlz[i]) giv2(i<<1, hlz[i]), giv2(i<<1|1, hlz[i]), hlz[i] = 0;
if(tag[i]) giv3(i<<1, tag[i]), giv3(i<<1|1, tag[i]), tag[i] = 0;
}
void add(int i, int l, int r, int x, int y, int v) {
if(x <= l && r <= y) { giv1(i, v); return; }
int mid = (l + r) >> 1; pd(i);
if(x <= mid) add(i<<1, l, mid, x, y, v);
if(y > mid) add(i<<1|1, mid+1, r, x, y, v);
sum[i] = sum[i<<1] + sum[i<<1|1];
}
void cop(int i, int l, int r, int x, int y) {
if(x <= l && r <= y) { giv2(i, 1); return; }
int mid = (l + r) >> 1; pd(i);
if(x <= mid) cop(i<<1, l, mid, x, y);
if(y > mid) cop(i<<1|1, mid+1, r, x, y);
hsum[i] = hsum[i<<1] + hsum[i<<1|1];
}
LL qry(int i, int l, int r, int x, int y) {
if(x <= l && r <= y) return hsum[i];
int mid = (l + r) >> 1; LL re = 0; pd(i);
if(x <= mid) re += qry(i<<1, l, mid, x, y);
if(y > mid) re += qry(i<<1|1, mid+1, r, x, y);
return re;
}
int b1[MAXV], b2[MAXV]; LL ans[MAXN];
int main () {
freopen("arithmetic.in", "r", stdin);
freopen("arithmetic.out", "w", stdout);
read(n), read(d), read(m);
if(m == 0) return 0;
for(int i = 1; i <= n; ++i) read(a[i]);
for(int i = 1, l, r; i <= m; ++i) read(l), read(r), q[r].pb(mp(l, i));
build(1, 1, n);
for(int i = 1, j = 1, cnt1 = 0, cnt2 = 0; i <= n; ++i) {
for(; top1 && a[q1[top1]] >= a[i]; --top1)
add(1, 1, n, q1[top1-1]+1, q1[top1], a[q1[top1]]/d);
q1[++top1] = i;
add(1, 1, n, q1[top1-1]+1, i, -(a[i]/d));
for(; top2 && a[q2[top2]] <= a[i]; --top2)
add(1, 1, n, q2[top2-1]+1, q2[top2], -(a[q2[top2]]/d));
q2[++top2] = i;
add(1, 1, n, q2[top2-1]+1, i, a[i]/d);
if(i > 1) add(1, 1, n, 1, i-1, -1);
cnt1 += (b1[a[i]%d]++ == 0);
cnt2 += (b2[a[i]]++ == 1);
for(; j <= i && (cnt1 > 1 || cnt2 > 0); ++j)
cnt1 -= (b1[a[j]%d]-- == 1),
cnt2 -= (b2[a[j]]-- == 2);
cop(1, 1, n, j, i);
for(int k = q[i].size()-1; k >= 0; --k)
ans[q[i][k].sc] = qry(1, 1, n, q[i][k].fr, i);
}
for(int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
}
Epidemic
這個代碼還有點問題。沒有特判一個環中,某一邊所有點都是關鍵點的情況。
#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0'); x*=flg;
}
typedef long long LL;
#define fr first
#define sc second
const int MAXN = 200005;
int n, m, c, g;
vector<int>a[MAXN];
void exgcd(int a, int b, int &x, int &y) {
if(!b) { x = 1; y = 0; return; }
exgcd(b, a%b, y, x), y -= x*(a/b);
}
pair<int,int>p[MAXN];
inline LL calc(int n, int m, vector<int>&a) {
int x, inv; exgcd(n, m, x, inv);
inv = (inv % n + n) % n;
int cnt = 0;
for(int i = 0, siz = a.size(); i < siz; ++i) p[++cnt] = pair<int,int>(1ll*a[i]*inv%n, a[i]);
sort(p + 1, p + cnt + 1); p[++cnt] = pair<int,int>(p[1].fr+n, p[1].sc);
LL re = 0;
for(int i = 2; i <= cnt; ++i) {
if(p[i].fr == p[i-1].fr) p[i].sc = p[i-1].sc;
if(p[i].fr-p[i-1].fr > 1) re = max(re, 1ll*(p[i].fr-p[i-1].fr-1)*m + p[i-1].sc);
}
return re;
}
inline LL solve(int n, int m, vector<int>&a) { return max(calc(n, m, a), calc(m, n, a)); }
int main () {
freopen("epidemic.in", "r", stdin);
freopen("epidemic.out", "w", stdout);
read(n), read(m); g = __gcd(n, m);
if(g >= MAXN) { puts("-1"); return 0; }
read(c); for(int i = 1, x; i <= c; ++i) read(x), a[x%g].push_back(x/g);
read(c); for(int i = 1, x; i <= c; ++i) read(x), a[x%g].push_back(x/g);
LL ans = 0;
for(int i = 0; i < g; ++i) {
if(a[i].empty()) { puts("-1"); return 0; }
ans = max(ans, 1ll*g*solve(n/g, m/g, a[i]) + i);
}
printf("%lld\n", ans);
}
Sort
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int MAXN = 100005;
const int MAXK = 15;
const int MAXS = (1<<12)+5;
inline void read(int &x) {
char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0'); x*=flg;
}
int n, k, fa[MAXN], sz[MAXN], cnt[MAXN];
int slen[MAXS], len[MAXK];
vector<int>dp[MAXN], inv[MAXN];
inline int qpow(int a, int b) {
int re=1;for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)re=1ll*re*a%mod;return re;
}
inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
int way, mx, msk[MAXK], s, bit[MAXS], sumf, sumg;
void dfs(int cur, int now) {
if(cur == k) {
int nway = 1ll * way * now % mod, nmx = mx;
for(int i = 1; i <= s; ++i) {
int x = slen[msk[i]];
nway = 1ll * nway * inv[x][cnt[x]++] % mod;
nmx = max(nmx, x);
}
if(nmx == 2) (sumf += now) %= mod;
else if(nmx > 2) (sumf += 2*now%mod) %= mod;
if(nmx <= 2) (sumg += now) %= mod;
else (sumg += nway) %= mod;
for(int i = 1; i <= s; ++i) --cnt[slen[msk[i]]];
return;
}
msk[++s] = 1<<cur;
dfs(cur+1, now); --s;
for(int i = 1; i <= s; ++i)
msk[i] ^= 1<<cur, dfs(cur+1, 1ll*now*(bit[msk[i]]-1)%mod), msk[i] ^= 1<<cur;
}
int main () {
freopen("sort.in", "r", stdin);
freopen("sort.out", "w", stdout);
read(n), read(k);
for(int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
for(int i = 1, x; i <= n; ++i) {
read(x);
if(x) {
int u = find(i), v = find(x);
if(u == v) ++cnt[sz[u]], sz[u] = -1;
else fa[u] = v, sz[v] += sz[u];
}
}
int cur = 0;
for(int i = 1; i <= n; ++i) if(fa[i] == i && sz[i] != -1) len[cur++] = sz[i];
for(int i = 0; i < (1<<cur); ++i) {
bit[i] = bit[i>>1] + (i&1);
for(int j = 0; j < cur; ++j) if(i>>j&1) slen[i] += len[j];
}
for(int i = 1; i <= n; ++i) {
dp[i].resize(n/i + 1);
dp[i][0] = 1;
for(int j = 1; j <= n/i; ++j) {
dp[i][j] = 1ll * dp[i][j-1] * i % mod;
if(j > 1) dp[i][j] = (dp[i][j] + 1ll * dp[i][j-2] * (j-1) * i) % mod;
}
inv[i].resize(n/i);
for(int j = 0; j < n/i; ++j) inv[i][j] = 1ll * dp[i][j+1] * qpow(dp[i][j], mod-2) % mod;
}
way = 1, mx = 0;
for(int i = 1; i <= n; ++i) {
way = 1ll * way * dp[i][cnt[i]] % mod;
if(cnt[i]) mx = i;
}
dfs(0, 1);
printf("%d\n%d\n", sumf, sumg);
}