@attack666
2020-12-18T18:42:15.000000Z
字数 75842
阅读 1063
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M;
int a[MAXN][21], lg2[MAXN];
int Query(int l, int r) {
int k = lg2[r - l + 1];
return max(a[l][k], a[r - (1 << k) + 1][k]);
}
int main() {
N = read(); M = read();
for(int i = 1; i <= N; i++) a[i][0] = read(), lg2[i] = (i == 1 ? 0 : lg2[i >> 1] + 1);
for(int j = 1; j <= 20; j++)
for(int i = 1; i + (1 << j) - 1 <= N; i++)
a[i][j] = max(a[i][j - 1], a[i + (1 << j - 1)][j - 1]);
while(M--) {
int l = read(), r = read();
cout << Query(l, r) << '\n';
}
return 0;
}
如题,已知一个数列,你需要进行下面三种操作:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, mod;
#define ls k << 1
#define rs k << 1 | 1
int add(int x, int y) {return (x + y + mod) % mod;}
int mul(int x, int y) {return 1ll * x * y % mod;}
void mul2(int &x, int y) {x = 1ll * x * y % mod;}
void add2(int &x, int y) {x = (x + y + mod) % mod;}
int sum[MAXN], tagm[MAXN], taga[MAXN], len[MAXN];
void ps(int k, int addv, int mulv) {
mul2(sum[k], mulv); add2(sum[k], mul(len[k], addv));
mul2(taga[k], mulv); add2(taga[k], addv);
mul2(tagm[k], mulv);
}
void pushdown(int k) {
if((!taga[k]) && (tagm[k] == 1)) return ;
ps(ls, taga[k], tagm[k]);
ps(rs, taga[k], tagm[k]);
taga[k] = 0; tagm[k] = 1;
return ;
}
void update(int k) {
sum[k] = add(sum[ls], sum[rs]);
}
void Build(int k, int l, int r) {
tagm[k] = 1; len[k] = r - l + 1;
if(l == r) {sum[k] = read(); return ;}
int mid = (l + r) >> 1;
Build(ls, l, mid); Build(rs, mid + 1, r);
update(k);
}
void IntMul(int k, int l, int r, int ql, int qr, int v) {
if(ql <= l && r <= qr) {ps(k, 0, v); return ;}
pushdown(k);
int mid = (l + r) >> 1;
if(ql <= mid) IntMul(ls, l, mid, ql, qr, v);
if(qr > mid) IntMul(rs, mid + 1, r, ql, qr, v);
update(k);
}
void IntAdd(int k, int l, int r, int ql, int qr, int v) {
if(ql <= l && r <= qr) {ps(k, v, 1); return ;}
pushdown(k);
int mid = (l + r) >> 1;
if(ql <= mid) IntAdd(ls, l, mid, ql, qr, v);
if(qr > mid) IntAdd(rs, mid + 1, r, ql, qr, v);
update(k);
}
int Query(int k, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return sum[k];
pushdown(k);
int mid = (l + r) >> 1, ans = 0;
if(ql <= mid) add2(ans, Query(ls, l, mid, ql, qr));
if(qr > mid) add2(ans, Query(rs, mid + 1, r, ql, qr));
return ans;
}
int main() {
N = read(); M = read(); mod = read();
Build(1, 1, N);
while(M--) {
int opt = read(), l = read(), r = read();
if(opt == 1) {
int val = read();
IntMul(1, 1, N, l, r, val);
} else if(opt == 2) {
int val = read();
IntAdd(1, 1, N, l, r, val);//puts("a");
} else {
cout << Query(1, 1, N, l, r) << '\n';
}
}
return 0;
}
蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列
题目描述
DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知
道N次操作后数列中所有元素的和。他还要玩其他游戏,所以这个问题留给你解决。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 8e6 + 10, INF = 1e9 + 10;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, rt, ls[MAXN], rs[MAXN], mx[MAXN], tot;
void IntMax(int &k, int l, int r, int ll, int rr, int val) {
if(!k) k = ++tot;
if(ll <= l && r <= rr) {chmax(mx[k], val); return ;}
int mid = l + r >> 1;
if(ll <= mid) IntMax(ls[k], l, mid, ll, rr, val);
if(rr > mid) IntMax(rs[k], mid + 1, r, ll, rr, val);
}
LL Query(int k, int l, int r, int val) {
chmax(mx[k], val); chmax(val, mx[k]);
if(l == r) return mx[k];
int mid = l + r >> 1;LL ans = 0;
if(ls[k]) ans += Query(ls[k], l, mid, val);
else ans += (mid - l + 1) * mx[k];
if(rs[k]) ans += Query(rs[k], mid + 1, r, val);
else ans += (r - mid) * mx[k];
return ans;
}
signed main() {
N = read();
for(int i = 1; i <= N; i++) {
int l = read(), r = read() - 1, k = read();
IntMax(rt, 1, INF, l, r, k);
}
printf("%lld\n", Query(rt, 1, INF, 0));
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define lb(x) (x & (-x))
const int MAXN = 2e6 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M;
int a[MAXN];
void add(int p, int v) {
while(p <= N) a[p] += v, p += lb(p);
}
int Que(int x) {
int ans = 0;
while(x) ans += a[x], x -= lb(x);
return ans;
}
int Query(int l, int r) {
return Que(r) - Que(l - 1);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
#endif
N = read(); M = read();
for(int i = 1; i <= N; i++) add(i, read());
while(M--) {
int opt = read();
if(opt == 1) {
int x = read(), val = read();
add(x, val);
} else {
int l = read(), r = read();
cout << Query(l, r) << '\n';
}
}
return 0;
}
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const int MAXN = 4e6 + 10, INF = 1e9 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, a[MAXN], date[MAXN], num;
void Des() {
for(int i = 1; i <= N; i++) date[i] = a[i];
sort(date + 1, date + N + 1);
num = unique(date + 1, date + N + 1) - date - 1;
for(int i = 1; i <= N; i++) a[i] = lower_bound(date + 1, date + num + 1, a[i]) - date;
}
int ls[MAXN], rs[MAXN], siz[MAXN], rt[MAXN], tot;
void insert(int &x, int pre, int l, int r, int pos) {
x = ++tot;
ls[x] = ls[pre]; rs[x] = rs[pre]; siz[x] = siz[pre] + 1;
if(l == r) return ;
int mid = (l + r) >> 1;
if(pos <= mid) rs[x] = rs[pre], insert(ls[x], ls[pre], l, mid, pos);
else ls[x] = ls[pre], insert(rs[x], rs[pre], mid + 1, r, pos);
}
int Query(int rl, int rr, int l, int r, int k) {
//cout << siz[k] << '\n';
if(l == r) return l;
int mid = (l + r) >> 1, usd = siz[ls[rr]] - siz[ls[rl]];
if(k <= usd) return Query(ls[rl], ls[rr], l, mid, k);
else return Query(rs[rl], rs[rr], mid + 1, r, k - usd);
}
int main() {
N = read(); M = read();
for(int i = 1; i <= N; i++) a[i] = read();
Des();
for(int i = 1; i <= N; i++) insert(rt[i], rt[i - 1], 1, num, a[i]);
while(M--) {
int l = read(), r = read(), k = read();
cout << date[Query(rt[l - 1], rt[r], 1, num, k)] << '\n';
}
return 0;
}
#include<bits/stdc++.h>
#define chmin(x, y) (x = x < y ? x : y)
#define chmax(x, y) (x = x > y ? x : y)
#define ls(x) T[k].ls
#define rs(x) T[k].rs
#define double long double
const double alpha(acos(-1) / 5);
const double cosa(cos(alpha));
const double sina(sin(alpha));
using namespace std;
const int MAXN = 1e6 + 10;
const double INF = 1e12 + 10, eps = 1e-11;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, WD, root, tot, num, ans[MAXN];
struct Point {
double x[2], r;
int id;
bool operator < (const Point &rhs) const {
return rhs.x[WD] - x[WD] > eps;
}
double operator [] (const int d) {
return x[d];
}
}P[MAXN];
int comp(const Point &a, const Point b) {
return a.r == b.r ? a.id < b.id : a.r > b.r;
}
struct Node {
int ls, rs, id;
double mx[2], mi[2];
Point p;
}T[MAXN];
void update(int k) {
for(int i = 0; i <= 1; i++) {
if(!ans[T[k].id]) T[k].mi[i] = T[k].p[i] - T[k].p.r, T[k].mx[i] = T[k].p[i] + T[k].p.r;
else T[k].mi[i] = INF, T[k].mx[i] = -INF;
if(ls(k)) chmin(T[k].mi[i], T[ls(k)].mi[i]), chmax(T[k].mx[i], T[ls(k)].mx[i]);
if(rs(k)) chmin(T[k].mi[i], T[rs(k)].mi[i]), chmax(T[k].mx[i], T[rs(k)].mx[i]);
}
}
int Build(int l, int r, int wd) {
if(l > r) return 0;
WD = wd; int mid = (l + r) >> 1, k = ++tot;
nth_element(P + l, P + mid, P + r + 1);
T[k].p = P[mid]; T[k].id = P[mid].id;
T[k].ls = Build(l, mid - 1, wd ^ 1) ;
T[k].rs = Build(mid + 1, r, wd ^ 1);
update(k);
return k;
}
double sqr(double x) {
return x * x;
}
bool judge(Point a, Point b) {
double tmp = sqr(a[0] - b[0]) + sqr(a[1] - b[1]);
return sqr(a.r + b.r) + eps - tmp > 0;
}
bool pd(int k, Point a) {
for(int i = 0; i <= 1; i++)
if((a[i] + a.r + eps < T[k].mi[i]) || (a[i] - a.r - eps > T[k].mx[i])) return 1;
return 0;
}
void Delet(int k, Point a) {
if(pd(k, a)) return ;
if(!ans[T[k].id] && judge(T[k].p, a)) ans[T[k].id] = a.id, T[k].p.r = -INF, num++;
if(ls(k)) Delet(ls(k), a);
if(rs(k)) Delet(rs(k), a);
update(k);
}
int main() {
//freopen("a.in", "r", stdin);
N = read();
for(int i = 1; i <= N; i++) {
double x = read(), y = read(), tx = x * cosa - y * sina, ty = x * sina + y * cosa;
P[i].x[0] = x; P[i].x[1] = y; P[i].r = read(), P[i].id = i;
}
root = Build(1, N, 0);
sort(P + 1, P + N + 1, comp);
for(int i = 1; i <= N; i++) if(!ans[P[i].id]) Delet(root, P[i]);
for(int i = 1; i <= N; i++) printf("%d ", ans[i]);
return 0;
}
#include<bits/stdc++.h>
template <typename A, typename B> inline bool chmax(A &x, B y) {return x < y ? x = y, 1 : 0;}
template <typename A, typename B> inline bool chmin(A &x, B y) {return x > y ? x = y, 1 : 0;}
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N;
#define ls(k) ch[k][0]
#define rs(k) ch[k][1]
int ch[MAXN][2], fa[MAXN], rev[MAXN], siz[MAXN], val[MAXN], tot, root;
int newnode(int _fa, int _val) {
int cur = ++tot;
fa[cur] = _fa; val[cur] = _val; rev[cur] = siz[cur] = 1;
return cur;
}
bool ident(int x) {
return ch[fa[x]][1] == x;
}
void connect(int x, int _fa, int tag) {
fa[x] = _fa; ch[_fa][tag] = x;
}
void update(int k) {
siz[k] = siz[ls(k)] + siz[rs(k)] + rev[k];
}
void rotate(int x) {
int y = fa[x], r = fa[y], yson = ident(x), rson = ident(y);
int B = ch[x][yson ^ 1];
connect(B, y, yson);
connect(x, r, rson);
connect(y, x, yson ^ 1);
update(y); update(x);
}
void splay(int x, int to) {//tag
if(x < 0) {
puts("G");
}
while(fa[x] != to) {
int y = fa[x];
if(fa[y] == to) rotate(x);
else if(ident(x) == ident(y)) rotate(x), rotate(x);
else rotate(y), rotate(x);
}
if(!to) root = x;
}
void Insert(int v) {
int now = root;
if(!now) {root = newnode(0, v); return ;}
while(now) {
siz[now]++;
if(val[now] == v) {rev[now]++; splay(now, 0); return ;}
int nxt = v > val[now];
if(!ch[now][nxt]) {ch[now][nxt] = newnode(now, v); splay(now, 0); return ;}
now = ch[now][nxt];
}
splay(now, 0);
}
int find(int v) {
int now = root;
while(now) {
if(val[now] == v) {splay(now, 0); return now;}
now = ch[now][v > val[now]];
}
puts("can't find v");
assert(1 == 2);
}
int rak(int v) {
int pos = find(v);
return siz[ls(pos)] + 1;
}
int kth(int k) {
int now = root;
while(now) {
int used = siz[now] - siz[rs(now)];
if(k > siz[ls(now)] && k <= used) return val[now];
else if(k <= siz[ls(now)]) now = ls(now);
else k -= used, now = rs(now);
}
puts("can't find kth");
assert(1 == 2);
}
int Pre(int v) {
int now = root, ans = 0;
while(now) {
if(val[now] < v) ans = now;
int nxt = (v <= val[now] ? 0 : 1);
now = ch[now][nxt];
}
assert(ans);
return ans;
}
int Nxt(int v) {
int now = root, ans = 0;
while(now) {
if(val[now] > v) ans = now;
int nxt = (v < val[now] ? 0 : 1);
now = ch[now][nxt];
}
assert(ans);
return ans;
}
void delet(int x) {
int pr = Pre(x), nx = Nxt(x);
splay(pr, 0); splay(nx, pr);
int pos = ch[nx][0];
if(rev[pos] > 1) rev[pos]--, splay(pos, 0);
else ch[nx][0] = 0, splay(nx, 0);
}
int main() {
N = read();
Insert(-INF); Insert(INF);
while(N--) {
int opt = read(), x = read();
if(opt == 1) Insert(x);
else if(opt == 2) delet(x);
else if(opt == 3) cout << rak(x) - 1 << '\n';
else if(opt == 4) cout << kth(x + 1) << '\n';
else if(opt == 5) cout << val[Pre(x)] << '\n';
else cout << val[Nxt(x)] << '\n';
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, a[MAXN];
#define ls(k) ch[k][0]
#define rs(k) ch[k][1]
int ch[MAXN][2], rev[MAXN], fa[MAXN], sum[MAXN], st[MAXN];
void update(int k) {
sum[k] = sum[ls(k)] ^ sum[rs(k)] ^ a[k];
}
void pushdown(int k) {
if(!rev[k]) return ;
swap(ls(k), rs(k));
rev[ls(k)] ^= 1;
rev[rs(k)] ^= 1;
rev[k] = 0;
}
bool isroot(int x) {
return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
}
bool ident(int x) {
return ch[fa[x]][1] == x;
}
void connect(int x, int _fa, int tag) {
fa[x] = _fa; ch[_fa][tag] = x;
}
void rotate(int x) {
int y = fa[x], r = fa[y], yson = ident(x), rson = ident(y);
int b = ch[x][yson ^ 1];
fa[x] = r;
if(!isroot(y)) connect(x, r, rson);//×¢Òâ¸üеÄÏȺó˳Ðò
connect(b, y, yson);
connect(y, x, yson ^ 1);
update(y); update(x);
}
void splay(int x) {
int y = x, top =0;
st[++top] = y;
while(!isroot(y)) st[++top] = (y = fa[y]);
while(top) pushdown(st[top--]);
for(int y = fa[x]; !isroot(x); rotate(x), y = fa[x])
if(!isroot(y))
rotate(ident(x) == ident(y) ? y : x);
}
void access(int x) {
for(int y = 0; x ; x = fa[y = x])
splay(x), rs(x) = y, update(x);
}
void makeroot(int x) {
access(x);
splay(x);
rev[x] ^= 1;
}
int findroot(int x) {
access(x); splay(x);
pushdown(x);
while(ls(x)) pushdown(ls(x)), x = ls(x);
splay(x);
return x;
}
void link(int x, int y) {
makeroot(x);
if(findroot(y) == x) return ;
fa[x] = y;
}
void cut(int x, int y) {
makeroot(x);
if(findroot(y) != x || fa[y] != x || ls(y)) return ;
fa[y] = 0; rs(x) = 0;
update(x);
}
void Modify(int x, int v) {
splay(x);
a[x] = v;
}
int Query(int x, int y) {
makeroot(x);
access(y); splay(y);
return sum[y];
}
int main() {
N = read(); M = read();
for(int i = 1; i <= N; i++) a[i] = read();
while(M--) {
int opt = read(), x = read(), y = read();
if(opt == 0) cout << Query(x, y) << '\n';
else if(opt == 1) link(x, y);
else if(opt == 2) cut(x, y);
else Modify(x, y);
}
return 0;
}
给定一棵有n个点的树,询问树上距离为k的点对是否存在。
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 10;
inline int read() {
int x;
cin >> x;
return x;
}
int N, M;
vector<Pair> v[MAXN];
void AE(int x, int y, int z) {
v[x].pb(MP(y, z));
}
Pair qr[MAXN];
int Root, Sum, mx[MAXN], siz[MAXN], vis[MAXN];
void FindRoot(int x, int fa) {
if(vis[x]) return ;
siz[x] = 1; mx[x] = 0;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i].fi;
if(to == fa || vis[to]) continue;
FindRoot(to, x);
siz[x] += siz[to];
mx[x] = max(mx[x], siz[to]);
}
mx[x] = max(mx[x], Sum - siz[x]);
if(mx[x] < mx[Root]) Root = x;
}
bool tim[10000001];
int cnt, val[MAXN];
void add(int x, int fa, int w) {
val[++cnt] = w;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i].fi;
if(to == fa || vis[to]) continue;
add(to, x, w + v[x][i].se);
}
}
void dfs(int x, int fa) {
tim[0] = 1;
queue<int> q;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i].fi;
if(to == fa || vis[to]) continue;
cnt = 0;
add(to, x, v[x][i].se);
//sort(val + 1, val + cnt + 1;
for(int j = 1; j <= cnt; j++)
for(int k = 1; k <= M; k++) {
if(qr[k].fi >= val[j]) qr[k].se |= tim[qr[k].fi - val[j]];
}
for(int j = 1; j <= cnt; j++)
tim[val[j]] = 1, q.push(val[j]);
}
while(!q.empty()) tim[q.front()] = 0, q.pop();
vis[x] = 1;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i].fi;
if(to == fa || vis[to]) continue;
Sum = siz[to]; Root = 0;
FindRoot(to, x);
dfs(Root, 0);
}
}
int main() {
//freopen("a.in", "r", stdin);
N = read(); M = read();
for(int i = 1; i < N; i++) {
int x = read(), y = read(), z = read();
AE(x, y, z); AE(y, x, z);
}
for(int i = 1; i <= M; i++) qr[i].fi = read();
Root = 0; mx[Root] = INF; Sum = N;
FindRoot(1, 0);
dfs(Root, 0);
for(int i = 1; i <= M; i++)
puts(qr[i].se ? "AYE" : "NAY");
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 4e6 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, R, mod;
int a[MAXN], dep[MAXN], id[MAXN], rev[MAXN], fa[MAXN], siz[MAXN], son[MAXN], top[MAXN], tim;
vector<int> v[MAXN];
void dfs1(int x, int _fa) {
fa[x] = _fa;
dep[x] = dep[fa[x]] + 1;
siz[x] = 1;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(to == _fa) continue;
dfs1(to, x);
siz[x] += siz[to];
if(siz[to] > siz[son[x]]) son[x] = to;
}
}
void dfs2(int x, int topf) {
top[x] = topf;
id[x] = ++tim;
rev[tim] = x;
if(!son[x]) return ;
dfs2(son[x], topf);
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(top[to]) continue;
dfs2(to, to);
}
}
#define ls k << 1
#define rs k << 1 | 1
int sum[MAXN], tag[MAXN], len[MAXN];
void update(int k) {
sum[k] = (sum[ls] + sum[rs]) % mod;
}
void Build(int k, int l, int r) {
len[k] = r - l + 1;
if(l == r) {sum[k] = a[rev[l]]; return ;}
int mid = (l + r) >> 1;
Build(ls, l, mid);
Build(rs, mid + 1, r);
update(k);
}
void ps(int k, int v) {
sum[k] = (sum[k] + 1ll * len[k] * v % mod) % mod;
tag[k] = (tag[k] + v) % mod;
}
void pushdown(int k) {
if(!tag[k]) return ;
ps(ls, tag[k]); ps(rs, tag[k]);
tag[k] = 0;
}
void Add(int k, int l, int r, int ql, int qr, int v) {
if(ql <= l && r <= qr) {ps(k, v); return ;}
int mid = (l + r) >> 1;
pushdown(k);
if(ql <= mid) Add(ls, l, mid, ql, qr, v);
if(qr > mid) Add(rs, mid + 1, r, ql, qr, v);
update(k);
}
int Query(int k, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return sum[k];
int mid = (l + r) >> 1, ans = 0;
pushdown(k);
if(ql <= mid) ans = (ans + Query(ls, l, mid, ql, qr)) % mod;
if(qr > mid) ans = (ans + Query(rs, mid + 1, r, ql, qr)) % mod;
return ans;
}
void Tadd(int x, int y, int v) {
while(top[x] ^ top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
Add(1, 1, N, id[top[x]], id[x], v);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
Add(1, 1, N, id[x], id[y], v);
}
int TQuery(int x, int y) {
int ans = 0;
while(top[x] ^ top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
ans = (ans + Query(1, 1, N, id[top[x]], id[x])) % mod;
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
return (ans + Query(1, 1, N, id[x], id[y])) % mod;
}
int main() {
N = read(); M = read(); R = read(); mod = read();
for(int i = 1; i <= N; i++) a[i] = read();
for(int i = 1; i < N; i++) {
int x = read(), y = read();
v[x].push_back(y);
v[y].push_back(x);
}
dfs1(R, 0);
dfs2(R, R);
Build(1, 1, N);
while(M--) {
int opt = read();
if(opt == 1) {
int x = read(), y = read(), z = read();
Tadd(x, y, z);
} else if(opt == 2) {
int x = read(), y = read();
cout << TQuery(x, y) << '\n';
} else if(opt == 3) {
int x = read(), z = read();
Add(1, 1, N, id[x], id[x] + siz[x] - 1, z);
} else if(opt == 4) {
int x = read();
cout << Query(1, 1, N, id[x] , id[x] + siz[x] - 1) << '\n';
}
}
return 0;
}
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 2000001;
inline int read() {
char c = getchar();int x = 0,f = 1;
while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9'){x = x * 10 + c - '0',c = getchar();}
return x * f;
}
#define Ls(k) s[k].ch[0]
#define Rs(k) s[k].ch[1]
struct sp {
int siz, ch[2], fa, rev, num;
} s[MAXN];
int sz;
inline void pushup(int k) { //上传splay标记
s[k].siz = s[s[k].ch[0]].siz + s[s[k].ch[1]].siz + s[k].rev;
}
inline int ident(int x) { // 判断x是父亲的哪个儿子
return s[s[x].fa].ch[1] == x;
}
inline void connect(int x, int f, int how) {
s[x].fa = f; s[f].ch[how] = x;
}
inline void rotate(int &root,int x) { // 对x进行双旋操作
int Y = s[x].fa, R = s[Y].fa, Yson = ident(x), Rson = ident(Y);
int B = s[x].ch[Yson ^ 1];
if(!R) root = x;
connect(x, R, Rson);
connect(Y, x, Yson ^ 1);
connect(B, Y, Yson);
pushup(Y); pushup(x);
}
inline void splay(int &root, int x, int to) { // tag
while(s[x].fa != to) {
int y = s[x].fa;
if(s[y].fa == to) rotate(root, x);
else if(ident(x) == ident(y)) rotate(root, y),rotate(root, x);
else rotate(root, x),rotate(root, x);
}
}
inline void insert(int &k, int c) { // k节点,插入值为c的元素
if(k == 0) {
k=++sz;
s[k].siz = s[k].rev = 1; s[k].num = c;
return ;
}
if(s[k].num==c) s[k].rev++;
else if(s[k].num < c) insert(Rs(k), c), s[Rs(k)].fa = k;
else insert(Ls(k), c), s[Ls(k)].fa = k;
pushup(k);
}
inline int getpre(int k,int val) { //小于val的最大值
int pos = k, ret;
while(pos) {
if(s[pos].num >= val) pos = Ls(pos);
else ret = pos, pos = Rs(pos);
}
return ret;
}
inline int getsuc(int k,int val) {
int pos = k, ret;
while(pos) {
if(s[pos].num <= val) pos = s[pos].ch[1];
else ret = pos, pos = s[pos].ch[0];
}
return ret;
}
inline int getk(int k,int val) {
if(s[k].num == val) return k;
if(s[k].num < val) return getk(Rs(k),val);
if(s[k].num > val) return getk(Ls(k),val);
}
#define ls k << 1
#define rs k << 1 | 1
struct node {
int l, r, root, mx, mn;
} T[MAXN];
inline void pushup_s(int k) { // 上传线段树的标记
T[k].mx = max(T[ls].mx, T[rs].mx);
T[k].mn = min(T[ls].mn, T[rs].mn);
}
inline void Build(int k,int l,int r) { //下标为k,左端点为l,右端点为r
T[k].l = l; T[k].r = r;
if(l == r) return ;
int mid = (l + r) >> 1;
Build(ls, l, mid);
Build(rs, mid + 1, r);// 线段树模板,没啥好说的,
}
inline void delet(int &k, int val) { //删除值为val的节点
int x = getk(k,val);//得到值为val的编号
if(s[x].rev > 1) {
s[x].rev--; s[x].siz--;
splay(k, x, 0);
} else {
int p = getpre(k, val),su = getsuc(k, val);// 找到前驱和后继
splay(k, p, 0); splay(k, su, p);// 把前驱旋转到根节点,把后继旋转到根节点的孩子
Ls(su) = 0;// 删除后继的左孩子,表示没有小于他的点,这样就成功把x节点删除
}
}
inline void build(int k, int pos, int x) { // 在下标为k,位置为pos的地方插入一个值为x的元素
insert(T[k].root, x);//在线段树root节点的splay中插入一个值为x的元素
if(T[k].l == T[k].r) {
T[k].mx = x; T[k].mn = x;
return ;
}
int mid = (T[k].l + T[k].r) >> 1;
if(pos <= mid) build(ls, pos, x);
if(pos > mid) build(rs, pos, x);
pushup_s(k);//别忘了上传线段树标记
}
int NewNode(int val, int f) {
s[++sz].rev = s[sz].siz = 1;
s[sz].num = val; s[sz].fa = f;
return sz;
}
inline void dfsseg(int k) { //对以k下标开始的线段树进行遍历
int x = getsuc(T[k].root, -1),
y = getpre(T[k].root, 1e8+1);//这样计算出来的x和y一定满足:x是k号线段树中的最小值的位置,y是k号线段树中最大值的位置
splay(T[k].root, x, 0);//将x旋转到根
s[x].siz++;
s[x].ch[0] = NewNode(-1, x);
splay(T[k].root, y, 0);
s[y].siz++;
s[y].ch[1] = NewNode(1e8 + 1, y);
if(T[k].l == T[k].r) return ;
dfsseg(ls);
dfsseg(rs);// 对于每一个线段,增加两个虚节点
}
inline int getmax(int k,int l,int r) { //在l到r中找最大的元素
if(l <= T[k].l && T[k].r <= r) return T[k].mx;
int mid=(T[k].l + T[k].r) >> 1,ret = -1;
if(l <= mid) ret = max(ret, getmax(ls, l, r));
if(mid < r) ret = max(ret, getmax(rs, l, r));
return ret;
}
inline int getmin(int k,int l,int r) { //在l到r中找最小的元素
if(l <= T[k].l && T[k].r <= r) return T[k].mn;
int mid = (T[k].l + T[k].r) >> 1,ret = 1e8+1;
if(l <= mid) ret = min(ret, getmin(ls, l, r));
if(mid < r) ret = min(ret, getmin(rs, l, r));
return ret;
}
inline int query_order(int k, int l, int r, int val) { //下标为k,查询val在区间l到r中有多少比它小的数
if(l <= T[k].l && T[k].r <= r) {
int p = getpre(T[k].root, val);
splay(T[k].root, p, 0);
return s[p].siz - s[Rs(p)].siz - 1;//
}
int mid = (T[k].l + T[k].r) >> 1, ret = 0;
if(l <= mid) ret += query_order(ls, l, r, val);
if(r > mid) ret += query_order(rs, l, r, val);
return ret;
}
inline void modify(int k,int pos,int pre,int now) { //在下标为k的线段树中的pos位置值为pre的节点的值修改为now
delet(T[k].root, pre);// 先把pre删掉
insert(T[k].root, now);// 再把now加上
if(T[k].l==T[k].r) {
T[k].mx = now; T[k].mn = now;
return ;
}
int mid = (T[k].l + T[k].r) >> 1;
if(pos <= mid) modify(ls , pos, pre, now);
if(pos > mid) modify(rs , pos, pre, now);
pushup_s(k);// 别忘了上传标记!
}
inline int query_pre(int k,int l,int r,int val) {//查询区间l到r内val的前驱
if(l <= T[k].l && T[k].r <= r) return s[getpre(T[k].root,val)].num;
int mid = (T[k].l + T[k].r) >> 1,ret = -1;
if(l <= mid) ret = max(ret, query_pre(ls, l, r, val));
if(mid < r) ret = max(ret, query_pre(rs, l, r, val));
return ret;
}
inline int query_suc(int k,int l,int r,int val) {//查询区间l到r内val的后继
if(l <= T[k].l && T[k].r <= r) return s[getsuc(T[k].root,val)].num;
int mid = (T[k].l + T[k].r) >> 1, ret = 1e8 + 1;
if(l <= mid) ret = min(ret, query_suc(ls, l, r, val));
if(mid < r) ret = min(ret, query_suc(rs, l, r, val));
return ret;
}
inline int QueryNum(int L,int R,int val) { // 在L到R的区间中查找val的排名
int l = 1, r = getmax(1, L, R), ret, tmp;
while(l <= r) { //二分答案
int mid = (l + r) >> 1;
tmp = query_order(1, L, R, mid);
if(tmp < val) ret = mid, l = mid + 1;
else r = mid - 1;
}
return ret;
}
int n, m;
int date[MAXN];
int main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#endif
n = read(); m = read();
Build(1, 1, n);//建好线段树
for(int i = 1; i <= n; i++) date[i] = read(); //读入初始数据
for(int i = 1; i <= n; i++)
build(1, i, date[i]);//把每一个元素都插到线段树里面去
dfsseg(1);// 把线段树的所有节点增加两个虚节点
while(m--) {
int l, r, k, pos, opt;
opt = read();
if(opt == 1) { //查询k在l到r中的排名
l = read(); r = read(); k = read();
printf("%d\n",query_order(1, l, r, k) + 1);
}
if(opt == 2) { // 查询排名为k的值
l = read(); r = read(); k = read();
printf("%d\n", QueryNum(l, r, k));
}
if(opt==3) { // 将pos位置的数修改为k
pos = read(); k = read();
modify(1, pos, date[pos], k);
date[pos] = k;//顺便修改date的值
}
if(opt==4) {
l = read(); r = read(); k = read();
int tmp = query_pre(1, l, r, k);// 查询tmp的前驱
if(tmp != -1) printf("%d\n", tmp);
else printf("-2147483647\n");
}
if(opt == 5) {
l = read(); r = read(); k = read();
int tmp = query_suc(1,l,r,k);
if(tmp != 1e8 + 1) printf("%d\n", tmp);
else printf("2147483647\n");
}
}
return 0;
}
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 1e3 + 10, INF = 1e9 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
vector<int> v[MAXN];
int N, M, E;
int link[MAXN], vis[MAXN], cur = 1;
int Aug(int x) {
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(vis[to] == cur) continue;
vis[to] = cur;
if(!link[to] || Aug(link[to])) {
link[to] = x;
return 1;
}
}
return 0;
}
main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
//freopen("b.out", "w", stdout);
#endif
int N = read(), M = read(), E = read();
for(int i = 1; i <= E; i++) {
int x = read(), y = read();
if(x <= N && y <= M) {
v[x].push_back(y);
}
}
int ans = 0;
for(int i = 1; i <= N; i++, cur++)
if(Aug(i)) ans++;
printf("%d\n", ans);
return 0;
}
#include<cstring>
#include<cstdio>
#define add_edge(x, y, z) AddEdge(x, y, z); AddEdge(y, x, 0);
#define min(x, y) x < y ? x : y
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 19, stdin), p1 == p2) ? EOF : *p1++)
#define rg register
const int MAXN = 10001, INF = 1e9 + 10;
char buf[1 << 19], *p1 = buf, *p2 = buf;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, S, T;
struct node {
int u, v, f, nxt;
}E[200002];
int head[MAXN], cur[MAXN], num = 0, deep[MAXN], vis[MAXN], q[MAXN];
inline void AddEdge(int x, int y, int z) {
E[num] = (node){x, y, z, head[x]};
head[x] = num++;
}
inline bool BFS() {
int l = 1, r = 1; q[r++] = S;
memset(deep, 0, sizeof(deep));
deep[S] = 1;
while(l < r) {
int p = q[l++];
for(rg int i = head[p]; i != -1; i = E[i].nxt) {
if(E[i].f && !deep[E[i].v]) {
deep[E[i].v] = deep[p] + 1;
if(E[i].v == T) return deep[T];
q[r++] = E[i].v;
}
}
}
return deep[T];
}
int DFS(int x, int flow) {
if(x == T) return flow;
int ansflow = 0;
for(rg int &i = cur[x]; i != -1; i = E[i].nxt) {
if(deep[E[i].v] == deep[x] + 1 && E[i].f) {
int canflow = DFS(E[i].v, min(E[i].f, flow));
flow -= canflow;
E[i].f -= canflow; E[i ^ 1].f += canflow;
ansflow += canflow;
if(flow <= 0) break;
}
}
return ansflow;
}
inline int Dinic() {
int ans = 0;
while(BFS()) {
memcpy(cur, head, sizeof(head));
ans += DFS(S, INF);
}
return ans;
}
int main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#endif
memset(head, -1, sizeof(head));
N = read(); M = read(); S = read(); T = read();
for(rg int i = 1; i <= M; i++) {
rg int x = read(), y = read(), z = read();
add_edge(x, y, z);
}
printf("%d", Dinic());
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10, INF = 1e9 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = 1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, S, T;
struct Edge {
int u, v, w, f, nxt;
}E[MAXN];
int head[MAXN], num = 0;
inline void AddEdge(int x, int y, int w, int f) {
E[num] = (Edge){x, y, w, f, head[x]};
head[x] = num++;
}
int anscost, ansflow, dis[MAXN], vis[MAXN], Pre[MAXN];
bool SPFA() {
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
queue<int> q; q.push(S); dis[S] = 0;
while(!q.empty()) {
int p = q.front(); q.pop(); vis[p] = 0;
for(int i = head[p]; i !=- 1; i = E[i].nxt) {
int to = E[i].v;
if(dis[to] > dis[p] + E[i].w && E[i].f) {
dis[to] = dis[p] + E[i].w;
Pre[to] = i;
if(!vis[to]) q.push(to), vis[to] = 1;
}
}
}
return dis[T] <= INF;
}
int F() {
int nowflow = INF;
for(int i = T; i != S; i = E[Pre[i]].u)
nowflow = min(nowflow, E[Pre[i]].f);
for(int i = T; i != S; i = E[Pre[i]].u)
E[Pre[i]].f -= nowflow, E[Pre[i] ^ 1].f += nowflow;
anscost += dis[T] * nowflow;
ansflow += nowflow;
}
void MCMF() {
while(SPFA())
F();
}
int main() {
memset(head, -1, sizeof(head));
N = read(); M = read(); S = read(); T = read();
for(int i = 1; i <= M; i++) {
int x = read(), y = read(), f = read(), w = read();
AddEdge(x, y, w, f);
AddEdge(y, x, -w, 0);
}
MCMF();
printf("%d %d", ansflow, anscost);
return 0;
}
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<ext/pb_ds/priority_queue.hpp>
#define MP(x, y) make_pair(x, y)
#define Pair pair<int, int>
using namespace std;
const int MAXN = 1e6 + 10, INF = 2147483646, B = 19;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = 1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, S;
struct Edge {
int u, v, w, nxt;
}E[MAXN];
int head[MAXN], num = 1;
void AddEdge(int x, int y, int z) {
E[num] = (Edge) {x, y, z, head[x]};
head[x] = num++;
}
int dis[MAXN], vis[MAXN];
priority_queue<Pair> q;
void Dij() {
for(int i = 1; i <= N; i++) dis[i] = 2147483647;
dis[S] = 0; q.push(MP(0, S));
while(!q.empty()) {
int p = q.top().second; q.pop();
if(vis[p]) continue; vis[p] = 1;
for(int i = head[p]; i != -1; i = E[i].nxt) {
int to = E[i].v;
if(dis[to] > dis[p] + E[i].w)
dis[to] = dis[p] + E[i].w,
q.push(MP(-dis[to], to));
}
}
for(int i = 1; i <= N; i++)
printf("%d ", dis[i]);
}
main() {
memset(head, -1, sizeof(head));
N = read(); M = read(); S = read();
for(int i = 1; i <= M; i++) {
int x = read(), y = read(), z = read();
AddEdge(x, y, z);
}
Dij();
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M;
int fa[MAXN];
struct Edge {
int u, v, w;
bool operator < (const Edge &rhs) const {
return w < rhs.w;
}
}E[MAXN];
int find(int x) {
return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
int unionn(int x, int y) {
x = find(x); y = find(y);
fa[x] = y;
}
int main() {
N = read(); M = read();
for(int i = 1; i <= N; i++) fa[i] = i;
for(int i = 1; i <= M; i++) {
int x = read(), y = read(), z = read();
E[i] = (Edge) {x, y, z};
}
sort(E + 1, E + M + 1);
int ans = 0;
for(int i = 1; i <= M; i++) {
int x = E[i].u, y = E[i].v;
if(find(x) == find(y)) continue;
ans += E[i].w;
unionn(x, y);
}
cout << ans;
return 0;
}
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 2e6 + 10, mod = 998244353;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, a[MAXN];
struct Edge {
int u, v, nxt;
}E[MAXN];
int head[MAXN], num = 1;
inline void AE(int x, int y) {
E[num] = (Edge) {x, y, head[x]};
head[x] = num++;
}
vector<int> v[MAXN];
int dfn[MAXN], low[MAXN], vis[MAXN], tim, st[MAXN], col[MAXN], top, cn, inter[MAXN];
int sum[MAXN], f[MAXN];
void tarjan(int x) {
dfn[x] = low[x] = ++tim;
vis[x] = 1;
st[++top] = x;
for(int i = head[x]; ~i; i = E[i].nxt) {
int to = E[i].v;
if(!dfn[to]) tarjan(to), low[x] = min(low[to], low[x]);
else if(vis[to]) low[x] = min(low[to], low[x]);
}
if(dfn[x] == low[x]) {
int h; cn++;
do {
h = st[top--];
col[h] = cn; sum[cn] += a[h]; vis[h] = 0;
}while(h != x);
}
}
void Topsort() {
queue<int> q;
for(int i = 1; i <= cn; i++) if(!inter[i]) q.push(i), f[i] = sum[i];
int ans = 0;
while(!q.empty()) {
int p = q.front(); q.pop();
ans = max(ans, f[p]);
for(auto to: v[p]) {
inter[to]--;
f[to] = max(f[to], f[p] + sum[to]);
if(!inter[to]) q.push(to);
}
}
cout << ans << '\n';
}
signed main() {
#ifndef ONLINE_JUDGE
freopen("a.in", "r", stdin); freopen("a.out", "w", stdout);
#endif
memset(head, -1, sizeof(head));
N = read(); M = read();
for(int i = 1; i <= N; i++) a[i] = read();
for(int i = 1; i <= M; i++) {
int x = read(), y = read();
AE(x, y);
}
for(int i = 1; i <= N; i++) if(!dfn[i]) tarjan(i);
for(int i = 1; i <= N; i++) {
for(int j = head[i]; ~j; j = E[j].nxt) {
int to = E[j].v;
if(col[i] != col[to]) {
v[col[i]].push_back(col[to]);
inter[col[to]]++;
}
}
}
Topsort();
return 0;
}
给出一个n个点,m条边的无向图,求图的割点。
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP make_pair
#define fi first
#define se second
using namespace std;
const int MAXN = 2e5 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, dfn[MAXN], low[MAXN], tot, cut[MAXN];
vector<int> v[MAXN];
void tarjan(int x, int fa) {
dfn[x] = low[x] = ++tot; int ch = 0;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(!dfn[to]) {
tarjan(to, x), low[x] = min(low[x], low[to]), ch++;
if(low[to] >= dfn[x] && (x != fa)) cut[x] = 1;
}
low[x] = min(low[x], dfn[to]);
}
if(x == fa && ch > 1) cut[x] = 1;
}
int main() {
N = read(); M = read();
for(int i = 1; i <= M; i++) {
int x = read(), y = read();
v[x].push_back(y); v[y].push_back(x);
}
for(int i = 1; i <= N; i++) if(!dfn[i]) tarjan(i, i);
int tot = 0;
for(int i = 1; i <= N; i++) if(cut[i]) tot++;
printf("%d\n", tot);
for(int i = 1; i <= N; i++) if(cut[i]) printf("%d ", i);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
//#define getchar() (S == T && (T = (S = BB) + fread(BB, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
//char BB[1 << 15], *S = BB, *T = BB;
using namespace std;
const int MAXN=1e5+10;
inline int read()
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct node
{
int u,v,nxt;
}edge[MAXN];
int head[MAXN],num=1;
inline void AddEdge(int x,int y)
{
edge[num].u=x;
edge[num].v=y;
edge[num].nxt=head[x];
head[x]=num++;
}
int N,M;
int angry[1001][1001];
int dfn[MAXN],low[MAXN],tot=0,point[MAXN],color[MAXN],in[MAXN],ans[MAXN];
stack<int>s;
void pre()
{
memset(angry,0,sizeof(angry));
num=1;
memset(head,-1,sizeof(head));
memset(ans,0,sizeof(ans));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
}
bool MakeColor(int now,int how)
{
color[now]=how;
for(int i=head[now];i!=-1;i=edge[i].nxt)
{
if(!in[edge[i].v]) continue;
if(!color[edge[i].v]&&!MakeColor(edge[i].v,how^1)) return 0;
else if(color[edge[i].v]==color[now]) return 0;
}
return 1;
}
void tarjan(int now,int fa)
{
dfn[now]=low[now]=++tot;
s.push(now);
for(int i=head[now];i!=-1;i=edge[i].nxt)
{
if(!dfn[edge[i].v]&&edge[i].v!=fa)
{
tarjan(edge[i].v,now);
low[now]=min(low[now],low[edge[i].v]);
if(low[edge[i].v]>=dfn[now])
{
memset(in,0,sizeof(in));//哪些在双联通分量里
memset(color,0,sizeof(color));
int h=0,cnt=0;
do
{
h=s.top();s.pop();
in[h]=1;
point[++cnt]=h;
}while(h!=edge[i].v);//warning
if(cnt<=1) continue;//必须构成环
in[now]=1;point[++cnt]=now;
if(MakeColor(now,1)==0)
for(int j=1;j<=cnt;j++)
ans[point[j]]=1;
}
}
if(edge[i].v!=fa) low[now]=min(low[now],dfn[edge[i].v]);
}
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
while(scanf("%d%d",&N,&M))
{
if(N==0&&M==0) break;
pre();
for(int i=1;i<=M;i++)
{
int x=read(),y=read();
angry[x][y]=angry[y][x]=1;
}
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
if(i!=j&&(!angry[i][j]))
AddEdge(i,j);
for(int i=1;i<=N;i++)
if(!dfn[i])
tarjan(i,0);
int out=0;
for(int i=1;i<=N;i++)
if(!ans[i]) out++;
printf("%d\n",out);
}
return 0;
}
对于一个字符串,求每次插入一个字符之后得到的本质不同的子串数
#include<bits/stdc++.h>
#define sit set<int>::iterator
#define LL long long
using namespace std;
const int MAXN = 2e5 + 10;
const int INF = 2333;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, L, rak[MAXN], tax[MAXN], tp[MAXN], sa[MAXN], H[MAXN], f[MAXN][20], lg2[MAXN], s[MAXN], date[MAXN], ans[MAXN];
set<int> st;
void Qsort() {
for(int i = 0; i <= M; i++) tax[i] = 0;
for(int i = 1; i <= N; i++) tax[rak[i]]++;
for(int i = 1; i <= M; i++) tax[i] += tax[i - 1];
for(int i = N; i >= 1; i--) sa[tax[rak[tp[i]]]--] = tp[i];
}
void SuffixSort() {
for(int i = 1; i <= N; i++) rak[i] = s[i], tp[i] = i; M = 233; Qsort();
for(int w = 1, p = 0; p < N; w <<= 1, M = p) { p = 0;
for(int i = 1; i <= w; i++) tp[++p] = N - i + 1;
for(int i = 1; i <= N; i++) if(sa[i] > w) tp[++p] = sa[i] - w;
Qsort(); swap(tp, rak); rak[sa[1]] = p = 1;
for(int i = 2; i <= N; i++) rak[sa[i]] = (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + w] == tp[sa[i - 1] + w]) ? p : ++p;
}
for(int i = 1, k = 0; i <= N; i++) {
if(k) k--; int j = sa[rak[i] - 1];
while(s[i + k] == s[j + k]) k++;
H[rak[i]] = k;
}
}
void Pre() {
for(int i = 1; i <= N; i++) f[i][0] = H[i];
for(int j = 1; j <= 17; j++)
for(int i = 1; i + (1 << j) - 1 <= N; i++) f[i][j] = min(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}
int Query(int x, int y) {
if(x > y) swap(x, y); x++;
int k = lg2[y - x + 1];
return min(f[x][k], f[y - (1 << k) + 1][k]);
}
void Des() {
sort(date + 1, date + N + 1);
int num = unique(date + 1, date + N + 1) - date - 1;
for(int i = 1; i <= N; i++) s[i] = lower_bound(date + 1, date + num + 1, s[i]) - date;
reverse(s + 1, s + N + 1);
}
int main() {
lg2[1] = 0; for(int i = 2; i <= MAXN - 1; i++) lg2[i] = lg2[i >> 1] + 1;
N = read();
for(int i = 1; i <= N; i++) s[i] = date[i] = read();
Des();
SuffixSort(); Pre();
st.insert(0); st.insert(N + 1);
LL now = 0; st.insert(rak[N]); ans[N] = 1;
printf("%lld\n", 1);
for(int i = N - 1; i >= 1; i--) {
sit nxt = st.upper_bound(rak[i]), pre;
if(*nxt == 0) pre = st.begin();
else pre = --nxt, nxt++;
// printf("%d %d\n", *pre, *nxt);
if(*pre != 0 && *nxt != N + 1) now -= Query(*pre, *nxt);
if(*pre != 0 && *pre != N + 1) now += Query(*pre, rak[i]);
if(*nxt != 0 && *nxt != N + 1) now += Query(rak[i], *nxt);
printf("%lld\n", 1ll * (N - i + 1) * ((N - i + 1) + 1) / 2 - now);
st.insert(rak[i]);
}
return 0;
}
题目同上
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 4e5 + 10;
int N, fa[MAXN], len[MAXN], las = 1, tot = 1, root = 1;
long long sum;
map<int, int> ch[MAXN];
long long Insert(int x) {
int now = ++tot, pre = las; las = now; len[now] = len[pre] + 1;
for(; pre && !ch[pre][x]; pre = fa[pre]) ch[pre][x] = now;
if(!pre) fa[now] = root;
else {
int q = ch[pre][x];
if(len[pre] + 1 == len[q]) fa[now] = q;
else {
int nq = ++tot; fa[nq] = fa[q]; len[nq] = len[pre] + 1;
ch[nq] = ch[q];
for(; pre && ch[pre][x] == q; pre = fa[pre]) ch[pre][x] = nq;
fa[now] = fa[q] = nq;
}
}
return sum += len[now] - len[fa[now]];
}
int main() {
cin >> N;
for(int i = 1; i <= N; i++) {
int x; cin >> x;
cout << Insert(x) << '\n';
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10;
char s[MAXN];
int len[MAXN], N, num[MAXN], fail[MAXN], last, cur, pos, trie[MAXN][26], tot = 1;
int getfail(int x, int i) {
while(i - len[x] - 1 < 0 || s[i - len[x] - 1] != s[i]) x = fail[x];
return x;
}
int main() {
scanf("%s", s);
N = strlen(s);
fail[0] = 1; len[1] = -1;
for(int i = 0; i <= N - 1; i++) {
if(i >= 1) s[i] = (s[i] + last - 97) % 26 + 97;
pos = getfail(cur, i);
if(!trie[pos][s[i] - 'a']) {
fail[++tot] = trie[getfail(fail[pos], i)][s[i] - 'a'];
trie[pos][s[i] - 'a'] = tot;
len[tot] = len[pos] + 2;
num[tot] = num[fail[tot]] + 1;
}
cur = trie[pos][s[i] - 'a'];
last = num[cur];
printf("%d ", last);
}
return 0;
}
有 N 个由小写字母组成的模式串以及一个文本串 T。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串 T 中出现的次数最多。
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int MAXN = 1e6 + 10, B = 26;
int T;
char s[201][75], a[MAXN];
int N;
int fail[MAXN], ch[MAXN][27], val[MAXN], root = 0, tot = 0, sum[MAXN];
void insert(char *s, int I) {
int N = strlen(s + 1);
int now = root;
for(int i = 1; i <= N; i++) {
int x = s[i] - 'a';
if(!ch[now][x]) ch[now][x] = ++tot;
now = ch[now][x];
}
val[now] = I;
}
void GetFail() {
queue<int> q;
for(int i = 0; i < B; i++) if(ch[root][i]) q.push(ch[root][i]);
while(!q.empty()) {
int p = q.front(); q.pop();
for(int i = 0; i < B; i++)
if(ch[p][i]) fail[ch[p][i]] = ch[fail[p]][i], q.push(ch[p][i]);
else ch[p][i] = ch[fail[p]][i];
}
}
int main() {
while(scanf("%d", &T) && T) {
memset(fail, 0, sizeof(fail)); memset(ch, 0, sizeof(ch));
memset(val, 0, sizeof(val)); memset(fail, 0, sizeof(fail));
memset(sum, 0, sizeof(sum)); memset(s, 0, sizeof(s));
for(int i = 1; i <= T; i++) scanf("%s", s[i] + 1), insert(s[i], i);
GetFail();
scanf("%s", a + 1);
int N = strlen(a + 1), now = root;
for(int i = 1; i <= N; i++) {
now = ch[now][a[i] - 'a'];
for(int t = now; t; t = fail[t]) if(val[t]) sum[val[t]]++;
}
int ans = 0;
for(int i = 1; i <= T; i++) ans = max(ans, sum[i]);
printf("%d\n", ans);
for(int i = 1; i <= T; i++)
if(sum[i] == ans)
printf("%s\n", s[i] + 1);
}
return 0;
}
给定一个非负整数序列{a},初始长度为N。
有M个操作,有以下两种操作类型:
1、Ax:添加操作,表示在序列末尾添加一个数x,序列的长度N+1。
2、Qlrx:询问操作,你需要找到一个位置p,满足l<=p<=r,使得:
a[p] xor a[p+1] xor ... xor a[N] xor x 最大,输出最大是多少。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 6e5 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-')f =- 1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, a[MAXN], sum[MAXN], cnt[MAXN * 25], ch[MAXN * 25][2], tot, root[MAXN];
void insert(int i, int x) {
x = (sum[i] = sum[i - 1] ^ x);
int p = root[i - 1], now = (root[i] = ++tot);
for(int i = 23; i >= 0; i--) {
bool nxt = x >> i & 1;
ch[now][nxt ^ 1] = ch[p][nxt ^ 1];
now = ch[now][nxt] = ++tot; p = ch[p][nxt];
cnt[now] = cnt[p] + 1;
}
}
int Query(int l, int r, int x) {
r = root[r], l = root[l];
int ans = 0;
for(int i = 23; i >= 0; i--) {
int nxt = x >> i & 1;
if(cnt[ch[r][nxt ^ 1]] - cnt[ch[l][nxt ^ 1]] > 0) ans += 1 << i, r = ch[r][nxt ^ 1], l = ch[l][nxt ^ 1];
else r = ch[r][nxt], l = ch[l][nxt];
}
return ans;
}
int main() {
N = read(); M = read();
for(int i = 1; i <= N; i++) a[i] = read(), insert(i, a[i]);
char ss[4];
for(int i = 1; i <= M; i++) {
scanf("%s", ss + 1);
if(ss[1] == 'A')
N++, a[N] = read(), insert(N, a[N]);
else {
int l = read() - 1, r = read() - 1, val = read();
printf("%d\n", Query(l - 1, r, val ^ sum[N]));
}
}
}
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
#define ull unsigned long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
#define pb push_back
using namespace std;
const int MAXN = 1e6 + 10, mod = 1e9 + 7, INF = 1e9 + 10;
const double eps = 1e-9;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, P[MAXN];
char s1[MAXN], s2[MAXN];
void GetFail() {
int j = 0;
for(int i = 2; i <= N; i++) {
while(j && s2[i] != s2[j + 1]) j = P[j];
if(s2[j + 1] == s2[i]) P[i] = ++j;
}
}
void KMP() {
int j = 0;
for(int i = 1; i <= N; i++) {
while(j && s1[i] != s2[j + 1]) j = P[j];
if(s1[i] == s2[j + 1]) j++;
if(j == M)
cout << (i - j + 1) << '\n';
}
}
signed main() {
scanf("%s", s1 + 1);
scanf("%s", s2 + 1);
N = strlen(s1 + 1); M = strlen(s2 + 1);
GetFail();
KMP();
for(int i = 1; i <= M; i++) cout << P[i] << ' ';
}
求字符串中回文串的最长长度
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
using namespace std;
const int MAXN = 11000000 * 2 + 1, mod = 1e9 + 7, INF = 1e9 + 10;
const double eps = 1e-9;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int ch(int x, int l, int r) {
return x >= l && x <= r;
}
char s[MAXN];
int N, ans[MAXN];
void trans() {
static char tmp[MAXN];
tmp[0] = '#';
for(int i = 1; i <= N; i++) {
tmp[2 * i - 1] = s[i];
tmp[2 * i] = '#';
}
memcpy(s, tmp, sizeof(s));
N = (N << 1) - 1;
int mx = 0, id = 0;
for(int i = 1; i <= N; i++) {
ans[i] = (mx > i ? min(mx - i, ans[id * 2 - i]) : 1);
while(i >= ans[i] && s[i - ans[i]] == s[i + ans[i]])
ans[i]++;
if(i + ans[i] > mx) mx = i + ans[i], id = i;
}
}
signed main() {
scanf("%s", s + 1);
N = strlen(s + 1);
trans();
int out = 0;
for(int i = 1; i <= N; i++) chmax(out, ans[i]);
cout << out - 1;
return 0;
}
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 2001, mod = 1e9 + 7;
const double eps = 1e-9;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, a[MAXN][MAXN];
int mul(int x, int y) {
return 1ll * x * y % mod;
}
int fp(int a, int p) {
int base = 1;
while(p) {
if(p & 1) base = mul(base, a);
a = mul(a, a); p >>= 1;
}
return base;
}
int inv(int x) {
return fp(x, mod - 2);
}
void add2(int &x, int y) {
if(x + y < 0) x = x + y + mod;
else x = (x + y >= mod) ? x + y - mod : x + y;
}
int MatrixInv() {
for(int i = 1; i <= N; i++)
a[i][i + N] = 1;
for(int i = 1; i <= N; i++) {
int mx = i;
for(int j = i + 1; j <= N; j++)
if(a[j][i] > a[i][i]) mx = j;
if(mx != i) swap(a[i], a[mx]);
if(!a[i][i]) return -1;
int Inv = inv(a[i][i]);
for(int j = i; j <= 2 * N; j++) a[i][j] = mul(a[i][j], Inv);
for(int j = 1; j <= N; j++) {
if(i != j) {
int r = a[j][i];
for(int k = i; k <= 2 * N; k++)
add2(a[j][k], -mul(a[i][k], r));
}
}
}
return 0;
}
signed main() {
//freopen("testdata.in", "r", stdin);
N = read();
for(int i = 1; i <= N; i++)
for(int j = 1; j <= N; j++)
a[i][j] = read();
if(MatrixInv() == -1) {puts("No Solution"); return 0;}
for(int i = 1; i <= N; i++, puts(""))
for(int j = N + 1; j <= 2 * N; j++)
printf("%d ", a[i][j]);
return 0;
}
国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。
我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。
在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的最短路径。
现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k,2)条 新通道。现在对于每个计划,我们想知道: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define int long long
#define LL long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 2e6 + 10, mod = 1e9 + 7, INF = 1e9 + 10;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline LL sqr(A x){return 1ll * x * x;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, dfn[MAXN];
vector<int> v[MAXN], E[MAXN];
namespace HLP {
int fa[MAXN], siz[MAXN], son[MAXN], dep[MAXN], top[MAXN], times;
void dfs1(int x, int _fa) {
siz[x] = 1; fa[x] = _fa; dep[x] = dep[_fa] + 1; dfn[x] = ++times;
for(auto &to : v[x]) {
if(to == _fa) continue;
dfs1(to, x);
siz[x] += siz[to];
if(siz[to] > siz[son[x]]) son[x] = to;
}
}
void dfs2(int x, int topf) {
top[x] = topf;
if(!son[x]) return ;
dfs2(son[x], topf);
for(auto &to : v[x]) {
if(top[to]) continue;
dfs2(to, to);
}
}
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 p[MAXN], st[MAXN], top, f[MAXN], mx[MAXN], mn[MAXN], siz2[MAXN], d[MAXN], ans1, ans2, ans3;
void AE(int x, int y) {E[x].push_back(y);}
int comp(int a, int b) {return dfn[a] < dfn[b];}
int dis(int x, int y) {if(dfn[x] > dfn[y]) swap(x, y); return HLP::dep[y] - HLP::dep[x];}
queue<int> q;
void insert(int x) {
if(top == 1) {st[++top] = x; return ;}
int lca = HLP::LCA(x, st[top]);
if(lca == st[top]) {st[++top] = x; return ;}
while(top > 1 && dfn[st[top - 1]] >= dfn[lca]) AE(st[top - 1], st[top]), top--;
if(lca != st[top])
AE(lca, st[top]), st[top] = lca;
st[++top] = x;
}
//ans1 和 ans2最大值 ans3最小值
void DP(int x) {
q.push(x);
mn[x] = (siz2[x] ? 0 : 1e18);
mx[x] = 0; d[x] = 0;
for(auto &to : E[x]) {
int w = dis(x, to);
assert(w <= N);
DP(to);
if(siz2[x] > 0) {
ans1 += w * siz2[to] * siz2[x] + siz2[to] * d[x] + siz2[x] * d[to];
chmax(ans2, mx[x] + mx[to] + w);
chmin(ans3, mn[x] + mn[to] + w);
}
chmax(mx[x], w + mx[to]);
chmin(mn[x], w + mn[to]);
siz2[x] += siz2[to];
d[x] += d[to] + w * siz2[to];
}
E[x].clear();
}
void work() {
ans1 = ans2 = 0; ans3 = INF;
int K = read(); st[top = 1] = 1;
for(int i = 1; i <= K; i++) p[i] = read();
sort(p + 1, p + K + 1, comp);
for(int i = 1; i <= K; i++) {
if(p[i] != 1) insert(p[i]);
siz2[p[i]] = 1;
}
while(top > 1) AE(st[top - 1], st[top]), top--;
DP(1);
while(!q.empty()) siz2[q.front()] = 0, q.pop();
cout << ans1 << ' ' << ans3 << ' ' << ans2 << '\n';
}
signed main() {
N = read();
for(int i = 1; i <= N - 1; i++) {
int x = read(), y = read();
v[x].push_back(y);
v[y].push_back(x);
}
HLP::dfs1(1, 0); HLP::dfs2(1, 1);
int Q = read();
while(Q--) {
work();
}
return 0;
}
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 1e5 + 10, INF = INT_MAX;
template<typename A, typename B> inline bool chmax(A &x, B y) {
return x < y ? x = y, 1 : 0;
}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, a[MAXN], f[MAXN][2];
struct Ma {
LL m[3][3];
Ma() {
memset(m, -0x3f, sizeof(m));
}
Ma operator * (const Ma &rhs) const {
Ma ans;
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= 2; j++)
for(int k = 1; k <= 2; k++)
chmax(ans.m[i][j], m[i][k] + rhs.m[k][j]);
return ans;
}
}val[MAXN], sum[MAXN];
vector<int> v[MAXN];
int ch[MAXN][2], fa[MAXN];
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
void update(int k) {
sum[k] = val[k];
if(rs(k)) sum[k] = sum[k] * sum[rs(k)];
if(ls(k)) sum[k] = sum[ls(k)] * sum[k];
}
bool ident(int x) {
return rs(fa[x]) == x;
}
bool isroot(int x) {
return ls(fa[x]) != x && rs(fa[x]) != x;
}
void connect(int x, int _fa, int tag) {
fa[x] = _fa;
ch[_fa][tag] = x;
}
void rotate(int x) {
int y = fa[x], r = fa[y], yson = ident(x), rson = ident(y);
int b = ch[x][yson ^ 1];
fa[x] = r;
if(!isroot(y)) connect(x, r, rson);
connect(b, y, yson);
connect(y, x, yson ^ 1);
update(y); update(x);
}
void splay(int x) {
for(int y = fa[x]; !isroot(x); rotate(x), y = fa[x])
if(!isroot(y))
rotate(ident(y) == ident(x) ? y : x);
}
void access(int x) {
for(int y = 0; x; x = fa[y = x]) {
splay(x);
if(rs(x)) {
val[x].m[1][1] += max(sum[rs(x)].m[1][1], sum[rs(x)].m[2][1]);
val[x].m[2][1] += sum[rs(x)].m[1][1];
}
if(y) {
val[x].m[1][1] -= max(sum[y].m[1][1], sum[y].m[2][1]);
val[x].m[2][1] -= sum[y].m[1][1];
}
val[x].m[1][2] = val[x].m[1][1];
rs(x) = y;
update(x);
}
}
int Modify(int p, int v) {
access(p); splay(p);
val[p].m[2][1] -= a[p] - v;
update(p);
a[p] = v;
splay(1);
return max(sum[1].m[1][1], sum[1].m[2][1]);
}
void dfs(int x, int _fa) {
fa[x] = _fa;
f[x][1] = a[x];
for(auto &to : v[x]) {
if(to == _fa) continue;
dfs(to, x);
f[x][0] += max(f[to][0], f[to][1]);
f[x][1] += f[to][0];
}
val[x].m[1][1] = f[x][0]; val[x].m[1][2] = f[x][0];
val[x].m[2][1] = f[x][1]; val[x].m[2][2] = -INF;
update(x);
// sum[x] = val[x];
}
int main() {
//freopen("a.in", "r", stdin);
N = read(); M = read();
for(int i = 1; i <= N; i++) a[i] = read();
for(int i = 1; i < N; i++) {
int x = read(), y = read();
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1, 0);
while(M--) {
int x = read(), y = read();
printf("%d\n", Modify(x, y));
}
return 0;
}
#include<bits/stdc++.h>
#define Pair pair<double, double>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define int long long
#define LL long long
#define db double
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 1e6 + 10, mod = 1e9 + 7, INF = 1e18 + 10;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline LL sqr(A x){return 1ll * x * x;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N;
struct Sta {
int id;
db h, w, x, y, f, ad;
void Get() {
x = 2 * h;
y = f + h * h - w;
}
}a[MAXN], st[MAXN];
vector<Pair> v;
int comp(const Sta &a, const Sta &b) {
return a.id < b.id;
}
double GetK(Pair a, Pair b) {
if((b.fi - a.fi) < eps) return INF;
return (b.se - a.se) / (b.fi - a.fi);
}
int sid[MAXN], cur;
void GetConvexHull(int l, int r) {
while(cur) sid[cur--] = 0;
v.clear();
for(int i = l; i <= r; i++) {
double x = a[i].x, y = a[i].y;
while((v.size() > 1 && ((GetK(v[v.size() - 1], MP(x, y)) < GetK(v[v.size() - 2], v[v.size() - 1])))) ||
((v.size() > 0) && (v[v.size() - 1].fi == x) && (v[v.size() - 1].se >= y)))
v.pop_back(), sid[cur--] = 0;
v.push_back(MP(x, y)); sid[++cur] = a[i].id;
}
}
int cnt = 0;
db Find(int id, db k) {
int tmp = v.size();
int l = 0, r = v.size() - 1, ans = 0;
while(l <= r) {
int mid = l + r >> 1;
if((mid == v.size() - 1) || (GetK(v[mid], v[mid + 1]) > k)) r = mid - 1, ans = mid;
else l = mid + 1;
}
return v[ans].se - k * v[ans].fi;
}
void CDQ(int l, int r) {
if(l == r) {
a[l].Get();
return ;
}
int mid = l + r >> 1;
CDQ(l, mid);
GetConvexHull(l, mid);
for(int i = mid + 1; i <= r; i++) {
chmin(a[i].f, Find(i, a[i].h) + a[i].ad);
}
CDQ(mid + 1, r);
int tl = l, tr = mid + 1, tot = tl - 1;
while(tl <= mid || tr <= r) {
if((tr > r) || (tl <= mid && a[tl].x < a[tr].x)) st[++tot] = a[tl++];//?????tl <= mid
else st[++tot] = a[tr++];
}
for(int i = l; i <= r; i++) a[i] = st[i];
}
signed main() {
N = read();
for(int i = 1; i <= N; i++) a[i].h = read();
for(int i = 1; i <= N; i++) {
a[i].w = read() + a[i - 1].w; a[i].id = i;
a[i].f = a[i - 1].f + sqr(a[i].h - a[i - 1].h);
a[i].ad = sqr(a[i].h) + a[i - 1].w;
if(i == 1) a[1].f = 0;
}
CDQ(1, N);
sort(a + 1, a + N + 1, comp);
// for(int i = 1; i <= N; i++) cout << i << ' ' << (LL)a[i].f << '\n';
cout << (LL)a[N].f;
return 0;
}
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define int long long
#define LL long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 1e6 + 10, mod = 1e9 + 7;
LL INF = 2e18 + 10;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline LL sqr(A x){return 1ll * x * x;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, w[MAXN], d[MAXN], s[MAXN], sw[MAXN], g[MAXN], f[MAXN], q[MAXN];
int calc(int l, int r) {
if(l > r) return 0;
return s[r] - s[l - 1] - d[l - 1] * (sw[r] - sw[l - 1]);
}
double Y(int x) {
return g[x];
}
double X(int x) {
return d[x];
}
double slope(int a, int b) {
return double(Y(b) - Y(a)) / (X(b) - X(a));
}
signed main() {
N = read();
for(int i = 1; i <= N; i++) w[i] = read(), d[i] = read();
reverse(w + 1, w + N + 1); reverse(d + 1, d + N + 1);
for(int i = 1; i <= N; i++) d[i] += d[i - 1], s[i] = s[i - 1] + w[i] * d[i], sw[i] = w[i] + sw[i - 1];
LL ans = INF;
for(int i = 1; i <= N; i++) g[i] = calc(1, i - 1)- s[i] + d[i] * sw[i];
q[1] = 0;
for(int i = 1, h = 1, t = 1; i <= N; i++) {
f[i] = INF;
while(h < t && slope(q[h], q[h + 1]) < sw[i - 1]) h++;
f[i] = g[q[h]] - d[q[h]] * sw[i - 1];
while(h < t && slope(q[t - 1], q[t]) > slope(q[t], i)) t--;
q[++t] = i;
//for(int j = i - 1; j >= 1; j--) chmin(f[i], g[j] - d[j] * sw[i - 1]);
f[i] += s[i - 1];
}
for(int i = 1; i <= N; i++)
f[i] += calc(i + 1, N), chmin(ans, f[i]);
cout << ans;
return 0;
}
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 2e7 + 10, mod = 20170408, SS = 1e5 + 10;
LL GG = 1e17;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
template<typename A, typename B> inline int add(A x, B y) {
if(x + y < 0) return x + y + mod;
else return x + y >= mod ? x + y - mod : x + y;
}
template<typename A, typename B> inline void add2(A &x, B y) {
if(x + y < 0) x = x + y + mod;
else x = (x + y >= mod ? x + y - mod : x + y);
}
template<typename A, typename B> inline int mul(A x, B y) {
return 1ll * x * y % mod;
}
int N, M, p, Lim;//1 - M, ºÍÊÇpµÄ±¶Êý
int f[SS], vis[MAXN], mu[MAXN], prime[MAXN], tot, cnt, num[SS], tim[SS], val[SS];
struct Ma {
int m[201][201];
Ma() {
memset(m, 0, sizeof(m));
}
void init() {
for(int i = 0; i <= Lim; i++) m[i][i] = 1;
}
void clear() {
memset(m, 0, sizeof(m));
}
void print() {
for(int i = 0; i <= Lim; i++, puts(""))
for(int j = 0; j <= Lim; j++)
printf("%d ", m[i][j]);
}
Ma operator * (const Ma &rhs) const {
Ma ans = {};
for(int i = 0; i <= Lim; i++)
for(int j = 0; j <= Lim; j++) {
__int128 tmp = 0;
for(int k = 0; k <= Lim; k++) {
tmp += 1ll * m[i][k] * rhs.m[k][j];
}
ans.m[i][j] = tmp % mod;
}
return ans;
}
}g;
Ma MatrixPow(Ma a, int p) {
Ma base; base.init();
while(p) {
if(p & 1) base = base * a;
a = a * a; p >>= 1;
}
return base;
}
void sieve(int N) {
vis[1] = 1; mu[1] = 1;
for(int i = 2; i <= N; i++) {
if(!vis[i]) prime[++tot] = i, mu[i] = -1;
for(int j = 1; j <= tot && i * prime[j] <= N; j++) {
vis[i * prime[j]] = 1;
if(i % prime[j]) mu[i * prime[j]] = -mu[i];
else {mu[i * prime[j]] = 0; break;}
}
}
for(int i = 1; i <= N; i++)
if(vis[i]) num[i % p]++;
}
int solve1() {//ºöÊÓÖÊÊýµÄÏÞÖÆ
for(int i = 1; i <= M; i++) f[i % p]++;
for(int j = 0; j < p; j++) {
memset(tim, 0, sizeof(tim));
memset(val, 0, sizeof(val));
int step = M;
for(int k = 1; k <= M; k++) {
int nxt = (j + k) % p;
if(tim[nxt]) {step = k - 1; break;}
tim[nxt] = 1; val[nxt]++;
}
if(step) for(int k = 0; k <= Lim; k++) g.m[k][j] = M / step * val[k];
for(int k = M / step * step + 1; k <= M; k++) g.m[(j + k) % p][j]++;
}
Ma ans = MatrixPow(g, N - 1);
int out = 0;
for(int i = 0; i <= Lim; i++) add2(out, mul(ans.m[0][i], f[i]));
return out;
}
int solve2() {//ÎÞÖÊÊý
memset(f, 0, sizeof(f));
g.clear();
for(int i = 1; i <= M; i++) f[i % p] += (vis[i]);
for(int j = 0; j < p; j++)
for(int k = 0; k < p; k++)
g.m[(j + k) % p][j] += num[k];
Ma ans = MatrixPow(g, N - 1);
int out = 0;
for(int i = 0; i <= Lim; i++)
add2(out, mul(ans.m[0][i], f[i]));
return out;
}
int main() {
N = read(); M = read(); Lim = p = read();
sieve(M);
cout << (solve1() - solve2() + mod) % mod;
return 0;
}
一个长为 n 的序列 a。
有 m 个询问,每次询问三个区间,把三个区间中同时出现的数一个一个删掉,问最后三个区间剩下的数的个数和,询问独立。
注意这里删掉指的是一个一个删,不是把等于这个值的数直接删完,
比如三个区间是 [1,2,2,3,3,3,3] , [1,2,2,3,3,3,3] 与 [1,1,2,3,3],就一起扔掉了 1 个 1,1 个 2,2 个 3。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<bitset>
#define LL long long
// #define int long long
using namespace std;
const int MAXN = 1e5 + 10, B = 25000;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M;
int a[MAXN], date[MAXN], L[MAXN][5], R[MAXN][5], belong[MAXN], base, cnt = 0, flag[MAXN], tim[MAXN], ans[MAXN];
struct Query {
int l, r, opt, id;
bool operator < (const Query &rhs) const {
return belong[l] == belong[rhs.l] ? belong[r] < belong[rhs.r] : belong[l] < belong[rhs.l];
}
}Q[MAXN * 3 + 1];
bitset<MAXN> bit[B + 50], now;
void Add(int x) {
tim[a[x]]++;
now.set(a[x] + tim[a[x]] - 1);
}
void Delet(int x) {
now.reset(a[x] + tim[a[x]] - 1);
tim[a[x]]--;
}
void solve(int ll, int rr) {
memset(flag, 0, sizeof(flag));
memset(tim, 0, sizeof(tim));
memset(ans, 0, sizeof(ans));
now.reset();
for(int i = 0; i <= B; i++) bit[i].reset();
cnt = 0;
for(int ti = ll; ti <= rr; ti++) {
for(int i = 1; i <= 3; i++)
Q[++cnt] = (Query){L[ti][i], R[ti][i], i, ti - ll + 1},
ans[ti - ll + 1] += (R[ti][i] - L[ti][i] + 1);
}
sort(Q + 1, Q + cnt + 1);
int l = 1, r = 0;
for(int i = 1; i <= cnt; i++) {
while(l > Q[i].l) Add(--l);
while(r < Q[i].r) Add(++r);
while(l < Q[i].l) Delet(l++);
while(r > Q[i].r) Delet(r--);
if(!flag[Q[i].id])
bit[Q[i].id] = now, flag[Q[i].id] = 1;
else
bit[Q[i].id] &= now;
}
// sort(Q + 1, Q + cnt + 1, comp);
for(int i = ll; i <= rr; i++)
printf("%d\n", ans[i - ll + 1] - bit[i - ll + 1].count() * 3);
}
main() {
/// freopen("xp1.in", "r", stdin);
// freopen("ans.out", "w", stdout);
N = read(); M = read(); base = sqrt(N);
for(int i = 1; i <= N; i++) a[i] = read(), date[i] = a[i], belong[i] = (i - 1) / base + 1;
sort(date + 1, date + N + 1);
for(int i = 1; i <= N; i++) a[i] = lower_bound(date + 1, date + N + 1, a[i]) - date;
for(int i = 1; i <= M; i++) {
//L1[i] = read(); R1[i] = read(); L2[i] = read(); R2[i] = read(); L3[i] = read(); R3[i] = read();
for(int j = 1; j <= 3; j++) L[i][j] = read(), R[i][j] = read();
}
for(int i = 1; i <= N; i += B + 1)
solve(i, min(i + B, M));
return 0;
}
/*
*/
#include<bits/stdc++.h>
const int MAXN = 1e5 + 10, INF = 1e9 + 7;
using namespace std;
template<typename A, typename B> inline bool chmax(A &x, B y) {
if(y > x) {x = y; return 1;}
else return 0;
}
template<typename A, typename B> inline bool chmin(A &x, B y) {
if(y < x) {x = y; return 1;}
else return 0;
}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, K, M, a[MAXN], l[MAXN], r[MAXN], tl[MAXN], tr[MAXN], belong[MAXN], block, cnt, ans[MAXN];
struct query {
int l, r, id;
bool operator < (const query &rhs) const {
return belong[l] == belong[rhs.l] ? r < rhs.r : belong[l] < belong[rhs.l];
}
};
vector<query> q[MAXN];
int solve(int l, int r) {
for(int i = l; i <= r; i++) tl[a[i]] = INF, tr[a[i]] = 0;
int ans = 0;
for(int i = l; i <= r; i++) {
int x = a[i];
chmin(tl[x], i), chmax(tr[x], i);
chmax(ans, tr[x] - tl[x]);
}
return ans;
}
int update(int x) {
chmax(tr[a[x]], x);
chmin(tl[a[x]], x);
return tr[a[x]] - tl[a[x]];
}
int update2(int x) {
int v = a[x];
chmax(r[v], x);
chmin(l[v], x);
return max(tr[v] - l[v], r[v] - l[v]);
}
void LxlDuLiu(vector<query> v, int id) {
int base = id * block, ll = base, rr = ll - 1, pre = 0, now = 0;
memset(tr, 0, sizeof(tr)); memset(r, 0, sizeof(r));
memset(tl, 0x3f, sizeof(tl)); memset(l, 0x3f, sizeof(l));
for(auto &x : v) {
//memset(l, 0x3f, sizeof(l)); memset(r, 0, sizeof(r));
while(rr < x.r) chmax(now, update(++rr));
pre = now;
while(ll > x.l) chmax(now, update2(--ll));
chmax(ans[x.id], now);
while(ll < base) r[a[ll]] = 0, l[a[ll]] = INF, ll++;
now = pre;
}
}
int main() {
// freopen("a.in", "r", stdin);
//freopen("b.out", "w", stdout);
N = read(); K = read(); M = read(); block = sqrt(N); int mx = 0;
for(int i = 1; i <= N; i++) a[i] = read(), belong[i] = (i - 1) / block + 1, chmax(mx, belong[i]);
for(int i = 1; i <= M; i++) {
int l = read(), r = read();
if(belong[l] == belong[r]) ans[i] = solve(l, r);
else q[belong[l]].push_back({l, r, i});
}
for(int i = 1; i <= mx; i++) sort(q[i].begin(), q[i].end());
for(int i = 1; i <= mx; i++)
LxlDuLiu(q[i], i);
for(int i = 1; i <= M; i++) printf("%d\n", ans[i]);
return 0;
}
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<cstdio>
#include<cmath>
#include<algorithm>
#define swap(x, y) x ^= y, y ^= x, x^= y
using namespace std;
const int MAXN= 2*1e6+10;
inline int read() {
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
return x*f;
}
char obuf[1<<24], *O=obuf;
void print(int x) {
if(x > 9) print(x / 10);
*O++ = x % 10 + '0';
}
int N, M;
int a[MAXN], where[MAXN];
struct Query {
int x, y, pre, id;
}Q[MAXN];
int Qnum = 0;
struct Change {
int pos,val;
}C[MAXN];
int Cnum = 0;
int color[MAXN], ans=0, base, out[MAXN];
int comp(const Query &a,const Query &b) {
return where[a.x] == where[b.x] ? ( where[a.y] == where[b.y] ? a.pre < b.pre : a.y < b.y ): a.x < b.x ;
}
void Add(int val){if(++color[val]==1) ans++; }
void Delet(int val){ if(--color[val]==0) ans--; }
void Work(int now, int i) {
if(C[now].pos >= Q[i].x && C[now].pos <= Q[i].y) {
if( --color[a[C[now].pos]] == 0 ) ans--;
if( ++color[C[now].val] == 1) ans++;
}
swap(C[now].val, a[C[now].pos]);
}
void MoQueue()
{
int l = 1, r = 0, now = 0;
for(int i = 1;i <= Qnum;i++)
{
while(l < Q[i].x) Delet(a[l++]);
while(l > Q[i].x) Add(a[--l]);
while(r < Q[i].y) Add(a[++r]);
while(r > Q[i].y) Delet(a[r--]);
while(now < Q[i].pre) Work(++now, i);
while(now > Q[i].pre) Work(now--, i);
out[Q[i].id] = ans;
}
for(int i = 1;i <= Qnum; i++)
print(out[i]), *O++ = '\n';
}
int main()
{
#ifdef WIN32
freopen("a.in", "r", stdin);
freopen("a.out","w",stdout);
#endif
N = read();M = read();
for(int i = 1;i <= N; i++) a[i] = read();
while(M--)
{
char opt[5];
scanf("%s",opt);
if(opt[0] == 'Q') {
Q[++Qnum].x = read();
Q[Qnum].y = read();
Q[Qnum].pre = Cnum;//????????????
Q[Qnum].id = Qnum;
}
else if(opt[0] == 'R') {
C[++Cnum].pos = read();
C[Cnum].val = read();
}
}
base = pow(N, 0.6666666666);
for(int i = 1; i <= N; i++) where[i] = i / base + 1;
sort(Q+1, Q+Qnum+1, comp);
MoQueue();
fwrite(obuf, O-obuf, 1, stdout);
return 0;
}
给定一个n个节点的树,每个节点表示一个整数,问u到v的路径上有多少个不同的整数。
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;
using namespace std;
const int MAXN = 1e5 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, Q;
int belong[MAXN], block;
struct Query {
int l, r, ID, lca, ans;
bool operator < (const Query &rhs) const{
return belong[l] == belong[rhs.l] ? r < rhs.r : belong[l] < belong[rhs.l];
// return belong[l] < belong[rhs.l];
}
}q[MAXN];
vector<int>v[MAXN];
int a[MAXN], date[MAXN];
void Discretization() {
sort(date + 1, date + N + 1);
int num = unique(date + 1, date + N + 1) - date - 1;
for(int i = 1; i <= N; i++) a[i] = lower_bound(date + 1, date + num + 1, a[i]) - date;
}
int deep[MAXN], top[MAXN], fa[MAXN], siz[MAXN], son[MAXN], st[MAXN], ed[MAXN], pot[MAXN], tot;
void dfs1(int x, int _fa) {
fa[x] = _fa; siz[x] = 1;
st[x] = ++ tot; pot[tot] = x;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(deep[to]) continue;
deep[to] = deep[x] + 1;
dfs1(to, x);
siz[x] += siz[to];
if(siz[to] > siz[son[x]]) son[x] = to;
}
ed[x] = ++tot; pot[tot] = x;
}
void dfs2(int x, int topfa) {
top[x] = topfa;
if(!son[x]) return ;
dfs2(son[x], topfa);
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(top[to]) continue;
dfs2(to, to);
}
}
int GetLca(int x, int y) {
while(top[x] != top[y]) {
if(deep[top[x]] < deep[top[y]]) swap(x, y);
x = fa[top[x]];
}
return deep[x] < deep[y] ? x : y;
}
void DealAsk() {
for(int i = 1; i <= Q; i++) {
int x = read(), y = read();
if(st[x] > st[y]) swap(x, y);
int _lca = GetLca(x, y);
q[i].ID = i;
if(_lca == x) q[i].l = st[x], q[i]. r = st[y];
else q[i].l = ed[x], q[i].r = st[y], q[i].lca = _lca;
}
}
int Ans, out[MAXN], used[MAXN], happen[MAXN];
void add(int x) {
if(++happen[x] == 1) Ans++;
}
void delet(int x) {
if(--happen[x] == 0) Ans--;
}
void Add(int x) {
used[x] ? delet(a[x]) : add(a[x]); used[x] ^= 1;
}
void Mo() {
sort(q + 1, q + Q + 1);
int l = 1, r = 0, fuck = 0;
for(int i = 1; i <= Q; i++) {
while(l < q[i].l) Add(pot[l]), l++, fuck++;
while(l > q[i].l) l--, Add(pot[l]), fuck++;
while(r < q[i].r) r++, Add(pot[r]), fuck++;
while(r > q[i].r) Add(pot[r]), r--, fuck++;
if(q[i].lca) Add(q[i].lca);
q[i].ans = Ans;
if(q[i].lca) Add(q[i].lca);
}
for(int i = 1; i <= Q; i++) out[q[i].ID] = q[i].ans;
for(int i = 1; i <= Q; i++)
printf("%d\n", out[i]);
}
int main() {
N = read(); Q = read();
//block = 1.5 * sqrt(2 * N) + 1;
//block = pow(N, 0.66666666666);
block = sqrt(N);
for(int i = 1; i <= N; i++) a[i] = date[i] = read();
for(int i = 1; i <= N * 2; i++) belong[i] = i / block + 1;
Discretization();
for(int i = 1; i <= N - 1; i++) {
int x = read(), y = read();
v[x].push_back(y); v[y].push_back(x);
}
deep[1] = 1; dfs1(1, 0);
dfs2(1, 1);
/* for(int i = 1; i <= N; i++)
for(int j = 1; j <= i - 1; j++)
printf("%d %d %d\n", i, j, GetLca(i, j));*/
DealAsk();
Mo();
return 0;
}
#include<bits/stdc++.h>
// #define int long long
using namespace std;
const int MAXN = 1e6 + 10, mod = 1000000007, mod2 = mod - 1;
template<typename A, typename B> inline int add(A x, B y) {
if(x + y < 0) return x + y + mod;
else return x + y >= mod ? x + y - mod : x + y;
}
template<typename A, typename B> inline int mul(A x, B y) {
return 1ll * x * y % mod;
}
template<typename A, typename B> inline void mul2(A &x, B y) {
x = 1ll * x * y % mod;
}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int f[MAXN], g[MAXN], vis[MAXN], prime[MAXN], mu[MAXN], tot;
int fp(int a, int p, int mod) {
int base = 1;
while(p) {
if(p & 1) base = 1ll * base * a % mod;
a = 1ll * a * a % mod; p >>= 1;
}
return base;
}
int inv(int x) {
if(x == 0) return 1;
return fp(x, mod - 2, mod);
}
void sieve(int N) {
f[0] = 0; f[1] = 1;
for(int i = 2; i <= N; i++) f[i] = add(f[i - 1], f[i - 2]);
vis[1] = 1; mu[1] = 1;
for(int i = 2; i <= N; i++) {
if(!vis[i]) prime[++tot] = i, mu[i] = -1;
for(int j = 1; j <= tot && i * prime[j] <= N; j++) {
vis[i * prime[j]] = 1;
if(i % prime[j]) mu[i * prime[j]] = -mu[i];
else {mu[i * prime[j]] = 0; break;}
}
}
fill(g + 1, g + N + 1, 1);
for(int d = 1; d <= N; d++) {
int t1 = fp(f[d], mod2 - 1, mod), t2 = f[d];
for(int T = d; T <= N; T += d) {
if(mu[T / d] == -1) g[T] = mul(g[T],t1);
else if(mu[T / d] == 1) g[T] = mul(g[T], f[d]);
}
}
g[0] = 1;
for(int i = 1; i <= N; i++) mul2(g[i], g[i - 1]);
}
int N, M, pre;
void solve() {
N = read(); M = read();
if(N > M) swap(N, M);
int ans = 1, tmp;
for(int i = 1, j; i <= N; i = j + 1) {
j = min(N / (N / i), M / (M / i));
mul2(ans, fp(mul(g[j], inv(g[i - 1])), 1ll * (N / i) * (M / i) % mod2, mod));
}
cout << ans << '\n';
}
signed main() {
sieve(1e6);
int T = read();
pre = T;
for(; T; T--, solve());
return 0;
}
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <map>
#define LL long long
using namespace std;
const int MAXN = 5000030;
inline int read() {
char c = getchar();
int x = 0, f = 1;
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
int N, limit = 5000000, tot = 0, vis[MAXN], mu[MAXN], prime[MAXN];
LL phi[MAXN];
void GetMuAndPhi() {
vis[1] = 1;
phi[1] = 1;
mu[1] = 1;
for (int i = 1; i <= limit; i++) {
if (!vis[i]) prime[++tot] = i, phi[i] = i - 1, mu[i] = -1;
for (int j = 1; j <= tot && i * prime[j] <= limit; j++) {
vis[i * prime[j]] = 1;
if (i % prime[j] == 0) {
mu[i * prime[j]] = 0;
phi[i * prime[j]] = phi[i] * prime[j];
break;
} else {
mu[i * prime[j]] = -mu[i];
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
for (int i = 1; i <= limit; i++) mu[i] += mu[i - 1], phi[i] += phi[i - 1];
}
map<int, LL> Aphi, Amu;
LL SolvePhi(LL n) {
if (n <= limit) return phi[n];
if (Aphi[n]) return Aphi[n];
LL tmp;
if (n & 1)
tmp = (n + 1) / 2LL * n;
else
tmp = n / 2LL * (n + 1);
for (int i = 2, nxt; i <= N; i = nxt + 1) {
nxt = min(n, n / (n / i));
tmp -= SolvePhi(n / i) * (LL)(nxt - i + 1);
if (nxt == n) break;
}
return Aphi[n] = tmp;
}
LL SolveMu(LL n) {
if (n <= limit) return mu[n];
if (Amu[n]) return Amu[n];
LL tmp = 1;
for (int i = 2, nxt; i <= N; i = nxt + 1) {
nxt = min(n, n / (n / i));
tmp -= SolveMu(n / i) * (LL)(nxt - i + 1);
if (nxt == n) break;
}
return Amu[n] = tmp;
}
int main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#else
#endif
GetMuAndPhi();
int QWQ;
scanf("%d", &QWQ);
while (QWQ--) {
scanf("%lld", &N);
printf("%lld %lld\n", SolvePhi(N), SolveMu(N));
}
return 0;
}
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define int long long
#define LL long long
#define ull unsigned long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 10;;
int mod;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline LL sqr(A x){return 1ll * x * x;}
template <typename A, typename B> inline LL fp(A a, B p, int md = mod) {int b = 1;while(p) {if(p & 1) b = mul(b, a);a = mul(a, a); p >>= 1;}return b;}
template <typename A> A inv(A x) {return fp(x, mod - 2);}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int a, b, X1, End;
//x_{i+1} = (aX_i + b) % P
//a^ans = x % p
//a^{i * k - j} = x % p
//a^{i * k} = x * a^j % p
map<int, int> mp;
/*
int Query(int a, int x, int p) {
if(__gcd(a, p) != 1) return -2;
int base = 1;
for(int i = 0; i <= p; i++) {
if(base % p == x) return i;
mul2(base, a);
}
return -2;
}
*/
int Query(int a, int x, int p) {
if(__gcd(a, p) != 1) return -2;
mp.clear(); int block = ceil(sqrt(p)), base = fp(a, block);
for(int i = 0, cur = x; i <= block; i++, mul2(cur, a)) mp[cur] = i;
for(int i = 1, cur = base; i <= block; i++, mul2(cur, base))
if(mp[cur])
return i * block - mp[cur];
return -2;
}
void solve() {
mod = read(); a = read(); b = read(); X1 = read(); End = read();
if(X1 == End) {puts("1"); return ;}
if(!a) {
if(!b) {puts(End == X1 ? "1" : "-1");return ;}
else {puts(End == b ? "2" : "-1");return ;}
}
if(a == 1) {
if(!b) {puts(End == X1 ? "1" : "-1");return ;}
else {
//int tmp = add(End, -X1 + mod) % b;
//cout << tmp << '\n';
cout << mul(add(End, -X1), inv(b)) + 1 << '\n';
return ;
}
}
int tmp = mul(b, inv(a - 1));
add2(X1, tmp); add2(End, tmp);
mul2(End, inv(X1));
cout << Query(a, End, mod) + 1 << '\n';
}
signed main() {
//freopen("a.in", "r", stdin);
for(int T = read(); T--; solve());
return 0;
}
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int x; cin >> x; return x;
}
int a, b, x, y;
int exgcd(int a, int b, int &x, int &y) {
if(!b) {x = 1; y = 0; return a;}
int r = exgcd(b, a % b, x, y);
int t = x; x = y, y = t - a / b * y;
return r;
}
int main() {
a = read(); b = read();
int r = exgcd(a, b, x, y);
while(x < 0) x += b;
cout << x;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, mod;
int mul(int x, int y) {return 1ll * x * y % mod;}
int add(int x, int y) {return (x + y + mod) % mod;}
int mul2(int &x, int y) {x = 1ll * x * y % mod;}
int add2(int &x, int y) {x = (x + y + mod) % mod;}
int fp(int a, int p) {
int base = 1;
while(p) {
if(p & 1) base = mul(base, a);
a = mul(a, a); p >>= 1;
}
return base;
}
int fac[MAXN], ifac[MAXN];
int C(int N, int M) {
if(N < M) return 0;
if((!N) || (!M)) return 1;
return mul(fac[N], mul(ifac[M], ifac[N - M]));
}
int Lucas(int N, int M) {
if(!N || !M) return 1;
if(N < M) return 0;
return mul(Lucas(N / mod, M / mod), C(N % mod, M % mod));
}
int main() {
int T = read();
while(T--) {
N = read(); M = read(); N += M; mod = read();
fac[0] = 1; int Lim = mod - 1;
for(int i = 1; i <= Lim; i++) fac[i] = mul(fac[i - 1], i);
ifac[Lim] = fp(fac[Lim], mod - 2);
for(int i = Lim; i >= 1; i--) ifac[i - 1] = mul(ifac[i], i);
cout << Lucas(N, M) << '\n';
}
return 0;
}
/*
2
2132 1311 91431
1 2 5
*/
// luogu-judger-enable-o2
#include<cstdio>
#define LL long long
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, Test[10] = {2, 3, 5, 7, 11, 13, 17};
int pow(int a, int p, int mod) {
int base = 1;
for(; p; p >>= 1, a = (1ll * a * a) % mod)
if(p & 1) base = (1ll * base * a) % mod;
return base % mod;
}
bool Query(int P) {
if(P == 1) return 0;
int t = P - 1, k = 0;
while(!(t & 1)) k++, t >>= 1;
for(int i = 0; i < 4; i++) {
if(P == Test[i]) return 1;
LL a = pow(Test[i], t, P), nxt = a;
for(int j = 1; j <= k; j++) {
nxt = (a * a) % P;
if(nxt == 1 && a != 1 && a != P - 1) return 0;
a = nxt;
}
if(a != 1) return 0;
}
return 1;
}
main() {
N = read(); M = read();
while(M--) puts(Query(read()) ? "Yes" : "No");
}
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 6e6 + 10, mod = 998244353, G = 3, Gi = 332748118;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, a[MAXN], b[MAXN], r[MAXN];
int mul(int x, int y) {
return 1ll * x * y % mod;
}
int add(int x, int y) {
return x + y >= mod ? x + y - mod : x + y;
}
int fp(int a, int p) {
int base = 1;
while(p) {
if(p & 1) base = mul(base, a);
a = mul(a, a); p >>= 1;
}
return base;
}
void NTT(int *A, int lim, int opt) {
for(int i = 0; i <= lim; i++) if(i < r[i]) swap(A[i], A[r[i]]);
for(int mid = 1; mid < lim; mid <<= 1) {
int wn = fp(opt == 1 ? G : Gi, (mod - 1) / (mid << 1));
for(int i = 0; i < lim; i += (mid << 1)) {
int w = 1;
for(int j = 0; j < mid; j++, w = mul(w, wn)) {
int x = A[i + j], y = mul(w, A[i + j + mid]);
A[i + j] = add(x, y);
A[i + mid + j] = add(x, mod - y);
}
}
}
if(opt == -1) {
int inv = fp(lim, mod - 2);
for(int i = 0; i <= lim; i++) {
a[i] = mul(a[i], inv);
}
}
}
int main() {
N = read(); M = read();
for(int i = 0; i <= N; i++) a[i] = read();
for(int i = 0; i <= M; i++) b[i] = read();
int lim = 1, l = 0;
while(lim <= N + M) lim <<= 1, l++;
for(int i = 1; i <= lim; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
NTT(a, lim, 1);
NTT(b, lim, 1);
for(int i = 0; i <= lim; i++) a[i] = mul(a[i], b[i]);
NTT(a, lim, -1);
for(int i = 0; i <= N + M; i++) cout << a[i] << ' ';
return 0;
}
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN = 1e7 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while (c < '0' || c > '9') {if (c == '-')f = -1; c = getchar();}
while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x * f;
}
const double Pi = acos(-1.0);
struct complex {
double x, y;
complex (double xx = 0, double yy = 0) {x = xx, y = yy;}
} a[MAXN], b[MAXN];
complex operator + (complex a, complex b) { return complex(a.x + b.x , a.y + b.y);}
complex operator - (complex a, complex b) { return complex(a.x - b.x , a.y - b.y);}
complex operator * (complex a, complex b) { return complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} //不懂的看复数的运算那部分
int N, M;
int l, r[MAXN];
int limit = 1;
void fast_fast_tle(complex *A, int type) {
for (int i = 0; i < limit; i++)
if (i < r[i]) swap(A[i], A[r[i]]); //求出要迭代的序列
for (int mid = 1; mid < limit; mid <<= 1) { //待合并区间的长度的一半
complex Wn( cos(Pi / mid) , type * sin(Pi / mid) ); //单位根
for (int R = mid << 1, j = 0; j < limit; j += R) { //R是区间的长度,j表示前已经到哪个位置了
complex w(1, 0); //幂
for (int k = 0; k < mid; k++, w = w * Wn) { //枚举左半部分
complex x = A[j + k], y = w * A[j + mid + k]; //蝴蝶效应
A[j + k] = x + y;
A[j + mid + k] = x - y;
}
}
}
}
int main() {
int N = read(), M = read();
for (int i = 0; i <= N; i++) a[i].x = read();
for (int i = 0; i <= M; i++) b[i].x = read();
while (limit <= N + M) limit <<= 1, l++;
for (int i = 0; i < limit; i++)
r[i] = ( r[i >> 1] >> 1 ) | ( (i & 1) << (l - 1) ) ;
// 在原序列中 i 与 i/2 的关系是 : i可以看做是i/2的二进制上的每一位左移一位得来
// 那么在反转后的数组中就需要右移一位,同时特殊处理一下奇数
fast_fast_tle(a, 1);
fast_fast_tle(b, 1);
for (int i = 0; i <= limit; i++) a[i] = a[i] * b[i];
fast_fast_tle(a, -1);
for (int i = 0; i <= N + M; i++)
printf("%d ", (int)(a[i].x / limit + 0.5));
return 0;
}
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
#define ull unsigned long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 4e5 + 10, INF = 1e9 + 10, INV2 = 499122177;
const double eps = 1e-9, pi = acos(-1);
const int G = 3, mod = 998244353;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
namespace Poly {
int rev[MAXN], GPow[MAXN], A[MAXN], B[MAXN], C[MAXN], lim;
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
int fp(int a, int p, int P = mod) {
int base = 1;
for(; p; p >>= 1, a = 1ll * a * a % P) if(p & 1) base = 1ll * base * a % P;
return base;
}
int GetLen(int x) {
int lim = 1;
while(lim < x) lim <<= 1;
return lim;
}
int GetLen2(int x) {
int lim = 1;
while(lim <= x) lim <<= 1;
return lim;
}
int GetOrigin(int x) {//¼ÆËãÔ¸ù
static int q[MAXN]; int tot = 0, tp = x - 1;
for(int i = 2; i * i <= tp; i++) if(!(tp % i)) {q[++tot] = i;while(!(tp % i)) tp /= i;}
if(tp > 1) q[++tot] = tp;
for(int i = 2, j; i <= x - 1; i++) {
for(j = 1; j <= tot; j++) if(fp(i, (x - 1) / q[j], x) == 1) break;
if(j == tot + 1) return i;
}
}
void Init(int Lim) {
for(int i = 1; i <= Lim; i++) GPow[i] = fp(G, (mod - 1) / i);
}
void NTT(int *A, int lim, int opt) {
int len = 0; for(int N = 1; N < lim; N <<= 1) ++len;
for(int i = 1; i <= lim; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1));
for(int i = 0; i <= lim; i++) if(i < rev[i]) swap(A[i], A[rev[i]]);
for(int mid = 1; mid < lim; mid <<= 1) {
int Wn = GPow[mid << 1];
for(int i = 0; i < lim; i += (mid << 1)) {
for(int j = 0, w = 1; j < mid; j++, w = mul(w, Wn)) {
int x = A[i + j], y = mul(w, A[i + j + mid]);
A[i + j] = add(x, y), A[i + j + mid] = add(x, -y);
}
}
}
if(opt == -1) {
reverse(A + 1, A + lim);
int Inv = fp(lim, mod - 2);
for(int i = 0; i <= lim; i++) mul2(A[i], Inv);
}
}
void Mul(int *a, int *b, int N, int M) {
memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B));
int lim = 1, len = 0;
while(lim <= N + M) len++, lim <<= 1;
for(int i = 0; i <= N; i++) A[i] = a[i];
for(int i = 0; i <= M; i++) B[i] = b[i];
NTT(A, lim, 1); NTT(B, lim, 1);
for(int i = 0; i <= lim; i++) B[i] = mul(B[i], A[i]);
NTT(B, lim, -1);
for(int i = 0; i <= N + M; i++) b[i] = B[i];
memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B));
}
void Inv(int *a, int *b, int len) {//B1 = 2B - A1 * B^2
if(len == 1) {b[0] = fp(a[0], mod - 2); return ;}
Inv(a, b, len >> 1);
for(int i = 0; i < len; i++) A[i] = a[i], B[i] = b[i];
NTT(A, len << 1, 1); NTT(B, len << 1, 1);
for(int i = 0; i < (len << 1); i++) mul2(A[i], mul(B[i], B[i]));
NTT(A, len << 1, -1);
for(int i = 0; i < len; i++) add2(b[i], add(b[i], -A[i]));
for(int i = 0; i < (len << 1); i++) A[i] = B[i] = 0;
}
void Dao(int *a, int *b, int len) {
for(int i = 1; i < len; i++) b[i - 1] = mul(i, a[i]); b[len - 1] = 0;
}
void Ji(int *a, int *b, int len) {
for(int i = 1; i < len; i++) b[i] = mul(a[i - 1], fp(i, mod - 2)); b[0] = 0;
}
void Ln(int *a, int *b, int len) {//G(A) = \frac{A}{A'} qiudao zhihou jifen
static int A[MAXN], B[MAXN];
Dao(a, A, len);
Inv(a, B, len);
NTT(A, len << 1, 1); NTT(B, len << 1, 1);
for(int i = 0; i < (len << 1); i++) B[i] = mul(A[i], B[i]);
NTT(B, len << 1, -1);
Ji(B, b, len << 1);
memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B));
}
void Exp(int *a, int *b, int len) {//F(x) = F_0 (1 - lnF_0 + A) but code ..why....
if(len == 1) return (void) (b[0] = 1);
Exp(a, b, len >> 1); Ln(b, C, len);
C[0] = add(a[0] + 1, -C[0]);
for(int i = 1; i < len; i++) C[i] = add(a[i], -C[i]);
NTT(C, len << 1, 1); NTT(b, len << 1, 1);
for(int i = 0; i < (len << 1); i++) mul2(b[i], C[i]);
NTT(b, len << 1, -1);
for(int i = len; i < (len << 1); i++) C[i] = b[i] = 0;
}
void Sqrt(int *a, int *b, int len) {
static int B[MAXN];
Ln(a, B, len);
for(int i = 0; i < len; i++) B[i] = mul(B[i], INV2);
Exp(B, b, len);
}
void Div(int *F, int *G, int *Q, int *R, int N, int M) {//F(n) = G(m) * Q(n - m + 1) + R(m)
static int Ginv[MAXN], TF[MAXN], TG[MAXN]; memset(Ginv, 0, sizeof(Ginv));
memcpy(TF, F, (N + 1) << 2); memcpy(TG, G, (M + 1) << 2);
reverse(F, F + N + 1); reverse(G, G + M + 1);
Inv(G, Ginv, GetLen2(N - M));//why not M
Mul(F, Ginv, N - M, N - M);
for(int i = 0; i <= N - M; i++) Q[i] = Ginv[i];
reverse(Q, Q + N - M + 1);
reverse(F, F + N + 1); reverse(G, G + M + 1);
Mul(Q, G, N - M, M);
for(int i = 0; i < M; i++) R[i] = add(F[i], -G[i]);
memcpy(F, TF, (N + 1) << 2); memcpy(G, TG, (M + 1) << 2);
}
void PowNum(int *a, int *b, int P, int N, int len) {
static int tx[MAXN], ty[MAXN]; memset(tx, 0, sizeof(tx)); memset(ty, 0, sizeof(ty));
Ln(a, tx, len);
for(int i = 0; i < N; i++) ty[i] = mul(P, tx[i]);
Exp(ty, b, len);
}
void MOD(int *A, int *B, int n, int m) {
static int Q[MAXN], R[MAXN];
Div(A, B, Q, R, n, m);
memcpy(A, R, m << 2);
}
void PowPoly(int *base, LL p, int *Mod, int m) {
static int res[MAXN], T[MAXN]; res[0] = 1;
while(p) {
if(p & 1) {
int lim = GetLen(m << 1);
memset(res + m, 0, lim - m << 2);;
memcpy(T, base, m << 2); memset(T + m, 0, lim - m << 2);
//Mul(T, res, lim, lim);
NTT(T, lim, 1); NTT(res, lim, 1);
for(int i = 0; i < lim; i++) res[i] = mul(res[i], T[i]);
NTT(res, lim, -1);
MOD(res, Mod, lim, m);
}
p >>= 1;
if(p) {
int lim = GetLen(m << 1);
memset(base + m, 0, lim - m << 2);
NTT(base, lim, 1);
for(int i = 0; i < lim; i++) base[i] = mul(base[i], base[i]);
NTT(base, lim, -1);
MOD(base, Mod, (m << 1) , m);
}
}
memcpy(base, res, m << 2);
}
int solve(int *f, int *a, LL n, int k) {
static int AA[MAXN], G[MAXN];
for(int i = 1; i <= k; i++) G[k - i] = (-f[i] + mod) % mod;
G[k] = AA[1] = 1;
PowPoly(AA, n, G, k);
int ans = 0;
for(int i = 0; i < k; i++) add2(ans, mul(AA[i], a[i]) - mod);
return ans;
}
int LRec(LL N, int K) {//a_n = \sum_{i=1}^k f_i * a_{n-i}
static int f[MAXN], a[MAXN];
Init(8 * K);
for(int i = 1; i <= K; i++) f[i] = read();
for(int i = 0; i < K; i++) a[i] = (read() + mod) % mod;
return solve(f, a, N, K);
}
};
using namespace Poly;
signed main() {
//freopen("testdata.in", "r", stdin);
LL N = read();int K = read();
cout << LRec(N, K);
return 0;
}
// luogu-judger-enable-o2
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int eps = 1e-10;
int dcmp(double x) {
if(fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
#define Point Vector
struct Vector {
double x, y;
Vector(double x = 0, double y = 0) : x(x), y(y) {};
bool operator < (const Vector &rhs) const {
return dcmp(x - rhs.x) == 0 ? y < rhs.y : x < rhs.x;
}
Vector operator - (const Vector &rhs) const {
return Vector(x - rhs.x, y - rhs.y);
}
};
double Cross(Vector A, Vector B) {
return A.x * B.y - A.y * B.x;
}
double dis(Point a, Point b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int N;
Point p[10001], q[10001];
int top;
void Push(Point p) {
while(Cross(q[top] - q[top - 1], p - q[top - 1]) < 0) top--;
q[++top] = p;
}
void Andrew() {
q[0] = q[top = 1] = p[1];
for(int i = 2; i <= N; i++) Push(p[i]);
for(int i = N - 1; i; --i) Push(p[i]);
}
int main() {
scanf("%d", &N);
for(int i = 1; i <= N; i++) scanf("%lf%lf", &p[i].x, &p[i].y);
sort(p + 1, p + N + 1);
Andrew();
double ans = 0;
for(int i = 1; i < top; i++)
ans += dis(q[i], q[i + 1]);
printf("%.2lf", ans);
return 0;
}
/*
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<vector>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
const int MAXN = 1001;
const double eps = 1e-10, Dlt = 0.97, INF = 1e9 + 7;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M;
struct Edge {
int u, v, w;
bool operator < (const Edge &rhs) const {
return w < rhs.w;
}
}E[MAXN];
int link[MAXN][MAXN], num, fa[MAXN];
void unionn(int x, int y) {
fa[x] = y;
}
int find(int x) {
if(fa[x] == x) return fa[x];
else return fa[x] = find(fa[x]);
}
vector<Pair> v[MAXN];
int dfs(int x, int cnt, int fa) {
int ans = 0;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i].fi, w = v[x][i].se;
if(to != fa) ans += dfs(to, cnt + 1, x) + w * cnt;
}
return ans;
}
int solve() {
int cur = INF, tot = 0, base = 0;
for(int i = 1; i <= N; i++) fa[i] = i, v[i].clear();
for(int i = 1; i <= M; i++) {
int x = E[i].u, y = E[i].v;
int fx = find(x), fy = find(y);
if(fx == fy) continue;
tot++; unionn(fx, fy);
v[x].push_back(MP(y, E[i].w));
v[y].push_back(MP(x, E[i].w));
}
if(tot != N - 1) return INF;
for(int i = 1; i <= N; i++)
cur = min(cur, dfs(i, 1, 0));
return cur;
}
int main() {
// freopen("testdata.in", "r", stdin);
srand((unsigned)time(NULL));
memset(link, 0x7f, sizeof(link));
N = read(); M = read();
if(N == 1) {
puts("0"); return 0;
}
for(int i = 1; i <= M; i++) {
int x = read(), y = read(), w = read();
link[x][y] = min(link[x][y], w);
link[y][x] = min(link[y][x], w);
}
for(int i = 1; i <= N; i++)
for(int j = i + 1; j <= N; j++)
if(link[i][j] <= INF)
E[++num] = (Edge) {i, j, link[i][j]};
sort(E + 1, E + num + 1);
int ans = solve();
int times = 200;
while(times--) {
int now = INF;
for(double T = 100000; T > eps; T *= Dlt) {
int x = rand() % num + 1, y = rand() % num + 1;
//check(x, y);
swap(E[x], E[y]);
int nxt = solve();
if(nxt < ans) {ans = nxt; continue;}
if(nxt < now || ((exp(now - nxt / T) < rand() / RAND_MAX))) {now = nxt; continue;}
swap(E[x], E[y]);
}
}
printf("%d", ans);
return 0;
}