#include<bits/stdc++.h>
using namespace std;constint maxn =1e5+10;struct node {longlongint sum, lazy;} segtree[maxn <<2];struct EDGE {int next, to;} edge[maxn <<1];int a[maxn], head[maxn], zson[maxn], fa[maxn], size[maxn], dep[maxn], top[maxn], tid[maxn], rnk[maxn];int n, m, r, p, cnt, x, y, z, dfsid, op;voidinit(){memset(segtree,0,sizeof segtree);memset(edge,0,sizeof edge);memset(head,0,sizeof head);memset(a,0,sizeof a);memset(zson,0,sizeof zson);memset(fa,0,sizeof fa);memset(dep,0,sizeof dep);memset(top,0,sizeof dep);memset(tid,0,sizeof tid);memset(rnk,0,sizeof rnk);
cnt = dfsid =0;}voidadd_edge(int x,int y){
edge[++cnt].next = head[x];
edge[cnt].to = y;
head[x]= cnt;}intdfs1(int x,int f,int deep){
dep[x]= deep;
fa[x]= f;
size[x]=1;for(int i = head[x]; i !=0; i = edge[i].next){int son = edge[i].to;if(son == f)continue;
size[x]+=dfs1(son, x, deep +1);if(size[son]> size[zson[x]]){
zson[x]= son;}}return size[x];}voiddfs2(int x,int t){
top[x]= t;
tid[x]=++dfsid;
rnk[dfsid]= x;if(zson[x]==0)return;dfs2(zson[x], t);for(int i = head[x]; i !=0; i = edge[i].next){int son = edge[i].to;if(son == fa[x]|| son == zson[x])continue;dfs2(son, son);}}voidpushup(int now){
segtree[now].sum = segtree[now <<1].sum + segtree[(now <<1)|1].sum;}voidbuild_tree(int l,int r,int now){
segtree[now].lazy =0;if(l == r){
segtree[now].sum = a[rnk[l]];return;}int mid = l +((r - l)>>1);build_tree(l, mid, now <<1);build_tree(mid +1, r,(now <<1)|1);pushup(now);}voidpushdown(int now,int l,int r){if(segtree[now].lazy ==0)return;
segtree[now <<1].lazy += segtree[now].lazy;
segtree[(now <<1)|1].lazy += segtree[now].lazy;int mid = l +((r - l)>>1);
segtree[now <<1].sum += segtree[now].lazy*(mid - l +1);
segtree[(now <<1)|1].sum += segtree[now].lazy*(r - mid);
segtree[now].lazy =0;}voidupdate(int L,int R,int l,int r,int c,int now){if(L <= l && R >= r){
segtree[now].lazy += c;
segtree[now].sum += c*(r - l +1);return;}pushdown(now, l , r);int mid = l +((r - l)>>1);if(L <= mid)update(L, R, l, mid, c, now <<1);if(R > mid)update(L, R, mid +1, r, c,(now <<1)|1);pushup(now);}longlongintquery(int L,int R,int l,int r,int now){if(L <= l && R >= r){return segtree[now].sum;}longlongint ans =0;pushdown(now, l, r);int mid = l +((r - l)>>1);if(L <= mid) ans +=query(L, R, l, mid, now <<1);if(R > mid) ans +=query(L, R, mid +1, r,(now <<1)|1);return ans%p;}longlongintsum(int x,int y){longlongint ans =0;int tx = top[x], ty = top[y];while(tx != ty){if(dep[tx]>= dep[ty]){
ans +=query(tid[tx], tid[x],1, n,1);
x = fa[tx];}else{
ans +=query(tid[ty], tid[y],1, n,1);
y = fa[ty];}
tx = top[x], ty= top[y];
ans %= p;}if(dep[x]>= dep[y]){
ans +=query(tid[y], tid[x],1, n,1);}else{
ans +=query(tid[x], tid[y],1, n,1);}return ans%p;}voidadd(int x,int y,int c){int tx = top[x], ty = top[y];while(tx != ty){if(dep[tx]>= dep[ty]){update(tid[tx], tid[x],1, n, c,1);
x = fa[tx];}else{update(tid[ty], tid[y],1, n, c,1);
y = fa[ty];}
tx = top[x], ty= top[y];}if(dep[x]>= dep[y]){update(tid[y], tid[x],1, n, c,1);}else{update(tid[x], tid[y],1, n, c,1);}}intmain(){while(scanf("%d %d %d %d",&n,&m,&r,&p)!=EOF){init();for(int i =0; i < n; i++){scanf("%d",&a[i]);}for(int i =0; i < n -1; i++){scanf("%d %d",&x,&y);add_edge(x, y);add_edge(y, x);}dfs1(r,-1,1);dfs2(r, r);build_tree(1, n,1);for(int i =0; i < m; i++){scanf("%d",&op);if(op ==1){scanf("%d %d %d",&x,&y,&z);add(x, y, z);}elseif(op ==2){scanf("%d %d",&x,&y);printf("%lld\n",sum(x, y)%p);}elseif(op ==3){scanf("%d %d",&x,&z);update(tid[x], tid[x]+ size[x]-1,1, n, z,1);}else{scanf("%d",&x);printf("%lld\n",query(tid[x], tid[x]+ size[x]-1,1, n,1)%p);}}}return0;}
L. 区间第 K 小
#include<cstdio>#include<vector>#include<algorithm>
using namespace std;constint maxn =2e5+10;struct node {int cnt, l, r;} segtree[maxn <<6];int tot, a[maxn], b[maxn], n, m, root[maxn];voidpushup(int pos){
segtree[pos].cnt = segtree[segtree[pos].l].cnt + segtree[segtree[pos].r].cnt;}intbuild_tree(int l,int r){int pos =++tot;if(l == r){
segtree[pos].cnt =0;return pos;}int mid = l +(r - l)/2;
segtree[pos].l =build_tree(l, mid);
segtree[pos].r =build_tree(mid +1, r);pushup(pos);return pos;}intupdate(int old,int l,int r,int tar){int pos =++tot;
segtree[pos]= segtree[old];if(l == r){
segtree[pos].cnt +=1;return pos;}int mid = l +(r - l)/2;if(tar <= mid) segtree[pos].l =update(segtree[old].l, l, mid, tar);else segtree[pos].r =update(segtree[old].r, mid +1, r, tar);pushup(pos);return pos;}intquery(int ri,int le,int k,int l,int r){if(l == r){return l;}int mid = l +(r - l)/2;int cnt = segtree[segtree[ri].l].cnt - segtree[segtree[le].l].cnt;if(cnt >= k)returnquery(segtree[ri].l, segtree[le].l, k, l, mid);elsereturnquery(segtree[ri].r, segtree[le].r, k - cnt, mid +1, r);}intmain(){while(scanf("%d %d",&n,&m)!=EOF){
tot =0;for(int i =0; i < n; i++){scanf("%d",&a[i]);
b[i]= a[i];}sort(b, b + n);int res =unique(b, b + n)- b;
root[0]=build_tree(0, n -1);for(int i =0; i < n; i++){int tar =lower_bound(b, b + res, a[i])- b;
root[i +1]=update(root[i],0, n -1, tar);}int l, r, k;for(int i =0; i < m; i++){scanf("%d %d %d",&l,&r,&k);int idx =query(root[r], root[l -1], k,0, n -1);printf("%d\n", b[idx]);}}return0;}
M. 区间求和
#include<cstdio>#include<cstring>constint maxn =1e5+10;typedeflonglongint LL;
LL segtree[maxn <<2], lazy[maxn <<2], a[maxn];voidpushup(int now){
segtree[now]= segtree[now <<1]+ segtree[(now <<1)|1];}voidbuild_tree(int l,int r,int now){if(l == r){
segtree[now]= a[l];return;}int mid = l +(r - l)/2;build_tree(l, mid, now <<1);build_tree(mid +1, r,(now <<1)|1);pushup(now);}voidpushdown(int now,int l,int r){if(lazy[now]==0)return;
lazy[now <<1]+= lazy[now];
lazy[(now <<1)|1]+= lazy[now];int mid = l +(r - l)/2;
segtree[now <<1]+= lazy[now]*(mid - l +1);
segtree[(now <<1)|1]+= lazy[now]*(r - mid);
lazy[now]=0;}voidupdate(int L,int R,int l,int r,int c,int now){if(L <= l && R >= r){
lazy[now]+= c;
segtree[now]+= c*(r - l +1);return;}pushdown(now, l , r);int mid = l +(r - l)/2;if(L <= mid)update(L, R, l, mid, c, now <<1);if(R > mid)update(L, R, mid +1, r, c,(now <<1)|1);pushup(now);}
LL query(int L,int R,int l,int r,int now){if(L <= l && R >= r){return segtree[now];}pushdown(now, l, r);int mid = l +(r - l)/2;
LL ans =0;if(L <= mid) ans +=query(L, R, l, mid, now <<1);if(R > mid) ans +=query(L, R, mid +1, r,(now <<1)|1);pushup(now);return ans;}intmain(){int n, m;while(scanf("%d %d",&n,&m)!=EOF){memset(segtree,0,sizeof segtree);memset(lazy,0,sizeof lazy);for(int i =1; i <= n; i++){scanf("%lld",&a[i]);}build_tree(1, n,1);char s[10];int x, y, z;for(int i =0; i < m; i++){scanf("%s", s);if(s[0]=='C'){scanf("%d %d %d",&x,&y,&z);update(x, y,1, n, z,1);}else{scanf("%d %d",&x,&y);printf("%lld\n",query(x, y,1, n,1));}}}return0;}
N. 区间最大公约数
#include<bits/stdc++.h>
using namespace std;constint maxn =1e5+10;longlongint a[maxn], segtree[maxn <<2];int n, q, T;longlongintgcd(longlongint a,longlongint b){return b ==0?a:gcd(b,a%b);}voidupdate(int now){
segtree[now]=gcd(segtree[now <<1], segtree[(now <<1)|1]);}voidbuild_tree(int l =1,int r = n,int now =1){if(l == r){
segtree[now]= a[l];return;}int mid = l +(r - l)/2;build_tree(l, mid, now <<1);build_tree(mid +1, r,(now <<1)|1);update(now);}longlongintquery(int L,int R,int now =1,int l =1,int r = n){if(L <= l && R >= r){return segtree[now];}longlongint ans =0;int mid = l +(r - l)/2;if(L <= mid) ans =gcd(ans,query(L, R, now <<1, l, mid));if(R > mid) ans =gcd(ans,query(L, R,(now <<1)|1, mid +1, r));return ans;}intmain(){//freopen("test.in", "r", stdin);//freopen("test.out", "w", stdout);scanf("%d",&T);for(int ca =1; ca <= T; ca++){scanf("%d",&n);for(int i =1; i <= n; i++){scanf("%lld",&a[i]);}build_tree();
map <longlongint,longlongint> mp;for(int i =1; i <= n; i++){int l = i, r = n, mid, vs, ans, pp;while(1){
ans = l;
pp = l;
vs =query(i, l);if(vs ==1) mp[vs]+=1LL*(n - l +1);while(l <= r){
mid =(l + r)>>1;if(query(i, mid)< vs) r = mid -1;else ans = mid, l = mid +1;
mp[vs]+=1LL*(ans - pp +1);
l = ans +1, r = n;if(l > r)break;}}printf("Case #%d:\n", ca);scanf("%d",&q);int l,r;for(int i =0;i < q; i++){scanf("%d %d",&l,&r);longlongint ans1 =query(l, r);printf("%lld %lld\n", ans1, mp[ans1]);}}return0;}
O. 很高兴你来了
#include<bits/stdc++.h>
using namespace std;constint maxn =5e6+10;unsignedint a[maxn], f[3*maxn], segtree[maxn <<2];unsignedint x, y, z;int n, m;voidinit(){memset(a,0,sizeof a);memset(f,0,sizeof f);memset(segtree,0,sizeof segtree);}unsignedintrng61(){
x = x^(x <<11);
x = x^(x >>4);
x = x^(x <<5);
x = x^(x >>14);unsignedint w = x^(y^z);
x = y;
y = z;
z = w;return z;}voidupdate(int L,int R,unsignedint l,unsignedint r,unsignedint v,int now){if(L <= l && R >= r){if(v > segtree[now]) segtree[now]= v;return;}int mid = l +(r - l)/2;if(L <= mid)update(L, R, l, mid, v, now <<1);if(R > mid)update(L, R, mid +1, r, v,(now <<1)|1);return;}voidpushdown(int now){if(segtree[now]> segtree[now <<1]) segtree[now <<1]= segtree[now];if(segtree[now]> segtree[(now <<1)|1]) segtree[(now <<1)|1]= segtree[now];}unsignedintquery(int l,int r,int now){if(l == r){return(unsignedint)l*segtree[now];}pushdown(now);int mid = l +(r - l)/2;unsignedint ans =0;
ans ^=query(l, mid, now <<1);
ans ^=query(mid +1, r,(now <<1)|1);return ans;}intmain(){int T, mod =pow(2,30);scanf("%d",&T);while(T--){scanf("%d %d %u %u %u",&n,&m,&x,&y,&z);for(int i =1;i <=3*m; i++){
f[i]=rng61();}unsignedint l, r, v;for(int i =1;i <= n; i++){
l =min(f[3*i -2]%n +1, f[3*i -1]%n +1);
r =max(f[3*i -2]%n +1, f[3*i -1]%n +1);
v = f[3*i]%mod;update(l, r,1, n, v,1);}printf("%u\n",query(1, n,1));}return0;}
P. 决战圆锥曲线
#include<cstdio>#include<cstring>#include<algorithm>#include<cctype>
using namespace std;typedeflonglong LL;inline LL gint(){char c =getchar();int f =1;while(c <'0'||c >'9'){if(c =='-'){
f =-1;}
c =getchar();}
LL a = c -'0';while((c =getchar())>='0'&& c <='9'){
a = a *10+ c -'0';}return a * f;}struct BufferReader {
LL x;BufferReader(LL x =0):x(x){}
LL nextInt(){
x =(x *100000005+20180821)%998244353;return x /100;}};constint maxn =100010;#define lson s << 1#define rson (s << 1)|1#define linfo s << 1,l,mid#define rinfo (s << 1)|1, mid + 1, rint miny[maxn <<2], maxy[maxn <<2];
bool inv[maxn <<2];inlinevoidup(int s){
miny[s]=min(miny[lson], miny[rson]);
maxy[s]=max(maxy[lson], maxy[rson]);}inlinevoidinverse(int s){
inv[s]^=1;
miny[s]=100000- miny[s];
maxy[s]=100000- maxy[s];swap(miny[s], maxy[s]);}inlinevoiddown(int s){if(inv[s]){inverse(lson);inverse(rson);
inv[s]=0;}}int A[maxn];voidbuild(int s,int l,int r){if(l == r){
miny[s]= maxy[s]= A[l];return;}int mid =(l + r)>>1;build(linfo);build(rinfo);up(s);}
LL a, b, c, ans;int ql, qr;voidchange(int s,int l,int r){if(l == r){
miny[s]= maxy[s]= qr;return;}down(s);int mid =(l + r)>>1;if(ql <= mid){change(linfo);}else{change(rinfo);}up(s);}voidupdate(int s,int l,int r){if(ql <= l && r <= qr){inverse(s);return;}down(s);int mid =(l + r)>>1;if(ql <= mid){update(linfo);}if(mid < qr){update(rinfo);}up(s);}inline LL calc(LL x,LL y){return a * x + b * y + c * x * y;}voidquery(int s,int l,int r){if(l == r){
ans =max(ans,calc(l, maxy[s]));return;}if(calc(min(r, qr), maxy[s])<= ans){return;}down(s);int mid =(l + r)>>1;if(qr <= mid){returnquery(linfo);}if(mid < ql){returnquery(rinfo);}
LL lans =calc(mid, maxy[lson]);
LL rans =calc(min(qr, r), maxy[rson]);if(lans < rans){query(rinfo);query(linfo);}else{query(linfo);query(rinfo);}}int n, m;intmain(){//freopen("test.in", "r", stdin);//freopen("test.out", "w", stdout);
n =gint();
m =gint();
BufferReader cin(gint());for(int i =1; i <= n; i++){
A[i]= cin.nextInt()%100001;}build(1,1, n);while(m--){char op =getchar();while(!isalpha(op)){
op =getchar();}if(op =='C'){
ql = cin.nextInt()% n +1;
qr = cin.nextInt()%100001;change(1,1, n);}elseif(op =='R'){
ql = cin.nextInt()% n +1;
qr = cin.nextInt()% n +1;if(ql > qr)swap(ql, qr);update(1,1, n);}else{
a =gint(), b =gint(), c =gint();
ql = cin.nextInt()% n +1;
qr = cin.nextInt()% n +1;if(ql > qr)swap(ql, qr);
ans =0;query(1,1, n);printf("%lld\n", ans);}}return0;}
Q. 敌兵布阵
#include <cstdio>
const int maxn = 200000;
long long int segtree[maxn << 2], a[maxn];
void pushup(int now) {
segtree[now] = segtree[now << 1] + segtree[(now << 1)|1];
}
void build_tree(int l, int r, int now) {
if (l == r) {
segtree[now] = a[l];
return;
}
int mid = l + (r - l)/2;
build_tree(l, mid, now << 1);
build_tree(mid + 1, r, (now << 1)|1);
pushup(now);
}
void update(int l, int r, int now, int tar, int c) {
if (l == r) {
segtree[now] += c;
return;
}
int mid = l + (r - l)/2;
if (tar <= mid) update(l, mid, now << 1, tar, c);
else update(mid + 1, r, (now << 1)|1, tar, c);
pushup(now);
}
long long int query(int L, int R, int l, int r, int now) {
if(L <= l && R >= r){
return segtree[now];
}
long long int ans = 0;
int mid = l + (r - l)/2;
if (L <= mid) ans += query(L, R, l, mid, now << 1);
if (R > mid) ans += query(L, R, mid + 1, r, (now << 1)|1);
return ans;
}
int main()
{
int T, n, x, y, ca = 0;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
}
build_tree(1, n, 1);
printf("Case %d:\n", ++ca);
char s[10];
while(scanf("%s", s), s[0] != 'E') {
scanf("%d %d", &x, &y);
if (s[0] == 'Q') {
printf("%lld\n", query(x, y, 1, n, 1));
} else if (s[0] == 'S') {
update(1, n, 1, x, -y);
} else {
update(1, n, 1, x, y);
}
}
}
return 0;
}