0428 模擬賽 Arithmetic Epidemic Sort

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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章