有的代码是现场写的可能比较难看,懒得改了……凑合看下吧。
找时间补补
分类讨论。
#include
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long ll;
struct Disjoint_Set_Union
{
int father[200005];
int size[200005];
int edge[200005];
int F[200005];
void reset(int n)
{
for(int i = 1; i <= n; i++)
father[i] = i;
fill(&size[1], &size[n]+1, 1);
fill(&edge[1], &edge[n]+1, 0);
fill(&F[1], &F[n]+1, 0);
}
int get_root(int i)
{
if(father[i] == i)
return i;
else
return father[i] = get_root(father[i]);
}
};
int main()
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
const int P = 10000019;
int t;
scanf("%d", &t);
static Disjoint_Set_Union dsu;
static bool vis[200005];
for(int _ = 1; _ <= t; _++) {
int n, m;
scanf("%d%d", &n, &m);
dsu.reset(m);
for(int _ = 1; _ <= n; _++) {
int a, b;
scanf("%d%d", &a, &b);
if(a == b) {
dsu.edge[dsu.get_root(a)]++;
dsu.F[dsu.get_root(a)]++;
}
else if(dsu.get_root(a) == dsu.get_root(b)) {
a = dsu.get_root(a);
dsu.edge[a]++;
}
else {
a = dsu.get_root(a);
b = dsu.get_root(b);
dsu.father[b] = a;
dsu.size[a] += dsu.size[b];
dsu.edge[a] += dsu.edge[b] + 1;
dsu.F[a] += dsu.F[b];
}
}
fill(&vis[0], &vis[m]+1, false);
int ans = 1;
for(int i = 1; i <= m; i++)
if(! vis[dsu.get_root(i)]) {
int j = dsu.get_root(i);
vis[j] = true;
if(dsu.edge[j] > dsu.size[j])
ans = 0;
else if(dsu.edge[j] == dsu.size[j] && ! dsu.F[j])
ans = ans * 2 % P;
else if(dsu.edge[j] == dsu.size[j] && dsu.F[j])
ans = ans;
else
ans = (long long)ans * dsu.size[j] % P;
}
printf("%d\n", ans);
}
}
类似均分纸牌,一个方向扫过去支付代价。
#include
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long ll;
const int N = 100010;
int cnt[N][2];
void solve() {
memset(cnt, 0, sizeof(cnt));
ll ans = 0;
int n;
scanf("%d", &n);
for (int rep = 0; rep < n * 2; ++rep) {
int x, y;
scanf("%d%d", &x, &y);
if (y < 1) {
ans += 1 - y;
y = 1;
}
if (y > 2) {
ans += y - 2;
y = 2;
}
if (x < 1) {
ans += 1 - x;
x = 1;
}
if (x > n) {
ans += x - n;
x = n;
}
++cnt[x][y - 1];
}
for (int i = 1; i <= n; ++i) {
#define A cnt[i][0]
#define B cnt[i][1]
--A;
--B;
if (A > 0 && B > 0) {
ans += A + B;
cnt[i + 1][0] += A;
cnt[i + 1][1] += B;
} else if (A <= 0 && B <= 0) {
ans -= A + B;
cnt[i + 1][0] += A;
cnt[i + 1][1] += B;
} else if (A <= 0 && B > 0) {
if (-A > B) {
ans += B;
A += B;
ans += abs(A);
cnt[i + 1][0] += A;
} else {
ans += -A;
B += A;
ans += abs(B);
cnt[i + 1][1] += B;
}
} else if (A > 0 && B <= 0) {
if (A > -B) {
ans += -B;
A += B;
ans += abs(A);
cnt[i + 1][0] += A;
} else {
ans += A;
B += A;
ans += abs(B);
cnt[i + 1][1] += B;
}
}
}
printf("%lld\n", ans);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int t;
scanf("%d",&t);
while(t--)
solve();
}
FWT 板子。
#include
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long ll;
const int N = 15;
int n, p, P;
int a[(1 << N) + 10], b[(1 << N) + 10];
int norm(int x) { return x >= p ? x - p : x; }
int Norm(int x) { return x >= P ? x - P : x; }
void fwt(int* a) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < 1 << n; ++j)
if (!(j >> i & 1)) {
int a0 = a[j], a1 = a[j | 1 << i];
a[j] = Norm(a0 + a1);
a[j | 1 << i] = Norm(a0 - a1 + P);
}
}
void deb(int* a) {
for (int i = 0; i < 1 << n; ++i)
LOG("%d ", a[i]);
LOG("\n");
}
void solve() {
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
int x, y, z;
scanf("%d%d%d%d%d", &n, &x, &y, &z, &p);
P = p << n;
while (x--) {
int l, r, c;
scanf("%d%d%d", &l, &r, &c);
c = norm(c % p + p);
a[l] = norm(a[l] + c);
a[r + 1] = norm(a[r + 1] - c + p);
}
for (int i = 1; i < 1 << n; ++i) a[i] = norm(a[i] + a[i - 1]);
while (y--) {
int l, r, c;
scanf("%d%d%d", &l, &r, &c);
c = norm(c % p + p);
b[l] = norm(b[l] + c);
b[r + 1] = norm(b[r + 1] - c + p);
}
for (int i = 1; i < 1 << n; ++i) b[i] = norm(b[i] + b[i - 1]);
fwt(a);
fwt(b);
for (int i = 0; i < 1 << n; ++i) a[i] = a[i] * (ll)b[i] % P;
fwt(a);
for (int i = 0; i < 1 << n; ++i) a[i] >>= n;
for (int i = 1; i < 1 << n; ++i) a[i] = norm(a[i] + a[i - 1]);
while (z--) {
int l, r;
scanf("%d%d", &l, &r);
int ans = a[r];
if (l)
ans = norm(ans - a[l - 1] + p);
printf("%d ", ans % p);
}
putchar('\n');
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int t;
scanf("%d", &t);
while (t--)
solve();
}
容斥一下,vector 上二分。
#include
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long ll;
const int N = 100010;
int n, m;
int a[N], mu[N];
vector<int> fac[N], ex[N];
void pre(int n) {
mu[1] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = i + i; j <= n; j += i)
mu[j] -= mu[i];
}
for (int i = 1; i <= n; ++i) {
if (!mu[i]) continue;
for (int j = i; j <= n; j += i)
fac[j].push_back(i);
}
}
void solve() {
fill(ex + 1, ex + 100001, vector<int>());
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
int x;
scanf("%d", &x);
for (int v : fac[x])
ex[v].push_back(i);
}
int d = 0;
while (m--) {
int l, r, x;
scanf("%d%d%d", &l, &r, &x);
l ^= d; r ^= d; x ^= d;
d = 0;
for (int v : fac[x])
d += mu[v] * (int)(upper_bound(ex[v].begin(), ex[v].end(), r) - lower_bound(ex[v].begin(), ex[v].end(), l));
printf("%d\n", d);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
pre(100000);
int t;
scanf("%d", &t);
while (t--) {
solve();
}
}
暴力。
#include
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long ll;
struct Time
{
int day;
int l, r;
};
int main()
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int t;
scanf("%d", &t);
for(int _ = 1; _ <= t; _++) {
int already[6];
for(int i = 1; i <= 5; i++)
scanf("%d", &already[i]);
int goal[6];
for(int i = 1; i <= 5; i++) {
scanf("%d", &goal[i]);
goal[i] = max(goal[i] - already[i], 0);
}
int n;
scanf("%d", &n);
int id[11], type[11], d[11];
vector<Time> time[11];
for(int i = 1; i <= n; i++) {
int k;
scanf("%d%d%d%d", &id[i], &type[i], &d[i], &k);
for(int _ = 1; _ <= k; _++) {
int day, l, r;
scanf("%d%d%d", &day, &l, &r);
time[i].push_back({day, l, r});
}
}
if(goal[1] + goal[2] + goal[3] + goal[4] + goal[5] > 25)
printf("unable to graduate\n");
else if(goal[1] == 0 && goal[2] == 0 && goal[3] == 0 && goal[4] == 0 && goal[5] == 0)
printf("able to graduate\n");
else {
vector<int> ans(100);
for(int sn = 2; sn < 1<<n+1; sn += 2) {
int cnt[6] = {};
for(int i = 1; i <= n; i++)
if(sn & (1<<i))
cnt[type[i]]++;
if(cnt[3] > 1 || cnt[4] > 1 || cnt[5] > 1)
continue;
if(cnt[1] + cnt[2] + cnt[3] + cnt[4] + cnt[5] >= ans.size())
continue;
//----------------------------------//
int score[6] = {};
for(int i = 1; i <= n; i++)
if(sn & (1<<i))
score[type[i]] += d[i];
if(score[1] + score[2] + score[3] + score[4] + score[5] > 25)
continue;
if(score[1] < goal[1] || score[2] < goal[2] || score[3] < goal[3] || score[4] < goal[4] || score[5] < goal[5])
continue;
//----------------------------------//
bool vis[7][13] = {};
for(int i = 1; i <= n; i++)
if(sn & (1<<i))
for(auto t : time[i])
for(int i = t.l; i <= t.r; i++) {
if(vis[t.day][i])
goto TAG;
else
vis[t.day][i] = true;
}
ans.clear();
for(int i = 1; i <= n; i++)
if(sn & (1<<i))
ans.push_back(id[i]);
TAG:;
}
if(ans.size() >= 98)
printf("unable to graduate\n");
else {
sort(ans.begin(), ans.end());
printf("able to graduate\n");
for(auto i : ans)
printf("%d ", i);
printf("\n");
}
}
}
}