快读
点击查看代码
template<typename type_of_scan>
inline void scan(type_of_scan &x){
type_of_scan f = 1;x = 0;char s = getchar();
while(s<'0'||s>'9'){if(s=='-')f = -1;s = getchar();}
while(s>='0'&&s<='9'){x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename type_of_print>
inline void print(type_of_print x){
if(x<0)putchar('-') , x = -x;
if(x>9)print(x/10);
putchar(x%10+'0');
}
高精度
点击查看代码
bool check(string s1 , string s2){
int len = s1.size() , len2 = s2.size();
if(len<len2)return 1;
if(len>len2)return 0;
for(int i=0;i<len;i++){
if(s1[i]<s2[i])return 1;
if(s1[i]>s2[i])return 0;
}
return 0;
}
int s1[200005] , s2[200005] , s3[200005];
void init(){
memset(s3,0,sizeof(s3));
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
}
struct big{
string s;
int len;
bool down;
big operator * (big B){//高精乘
init();
int len1 = len , len2 = B.len , len3 = len1 + len2;
reverse(s.begin(),s.end()) , reverse(B.s.begin(),B.s.end());
for(int i=0;i<len3;i++)s3[i] = 0 , s1[i] = (i < len1 ? s[i] - '0' : 0) , s2[i] = (i < len2 ? B.s[i] - '0' : 0);
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
int c1 = s1[i] , c2 = s2[j];
s3[i+j] += c1 * c2;
s3[i+j+1] += (s3[i+j] / 10);
s3[i+j] %= 10;
}
}
while(len3>1&&s3[len3-1]==0)len3--;
string ts = "";
for(int i=0;i<len3;i++)ts += (s3[i] + '0');
reverse(ts.begin(),ts.end());
reverse(s.begin(),s.end());
reverse(B.s.begin(),B.s.end());
return {ts,len3,down^B.down};
}
big operator - (big B){//高精减
init();
big ans = {"",0,0};
int len1 = len , len2 = B.len , len3 = max(len1,len2);
bool sw = 0;
if(check(s,B.s)){
ans.down = 1 , sw = 1 , swap(s,B.s);
}
reverse(s.begin(),s.end()) , reverse(B.s.begin(),B.s.end());
for(int i=0;i<len1;i++){
s1[i] = s[i] - '0' , s2[i] = (i < len2 ? B.s[i] - '0' : 0);
}
for(int i=0;i<len1;i++){
int c2 = s2[i];
s1[i] -= c2;
if(s1[i]<0)s1[i] += 10 , s1[i+1]--;
}
while(len3>1&&s1[len3-1]==0)len3--;
string ts = "";
for(int i=0;i<len3;i++)ts += (s1[i] + '0');
reverse(ts.begin(),ts.end());
reverse(s.begin(),s.end()) , reverse(B.s.begin(),B.s.end());
if(sw)swap(s,B.s);
ans.s = ts , ans.len = len3;
return ans;
}
big operator + (big B){//高精加
if((down^B.down)){
big thi = {s,len,down};
if(down){
return B - thi;
}else return thi - B;
}
int len1 = len , len2 = B.len , len3 = max(len1,len2) + 1;
init();
reverse(s.begin(),s.end()) , reverse(B.s.begin(),B.s.end());
for(int i=0;i<len3;i++){
s3[i] = 0;
s1[i] = (i < len1 ? s[i] - '0' : 0);
s2[i] = (i < len2 ? B.s[i] - '0' : 0);
}
for(int i=0;i<len3;i++){
int c1 = s1[i] , c2 = s2[i];
s3[i] += c1 + c2;
s3[i+1] += (s3[i] / 10);
s3[i] %= 10;
}
while(len3>1&&s3[len3-1]==0)len3--;
string ts = "";
for(int i=0;i<len3;i++)ts += (s3[i] + '0');
reverse(ts.begin(),ts.end());
reverse(s.begin(),s.end()) , reverse(B.s.begin(),B.s.end());
return {ts,len3,down&B.down};
}
}
CRT
点击查看代码
__int128 a[15] , b[15] , c[15] , n;
__int128 in(){
__int128 k = 0 , f = 1;
char c = getchar();
while(c<'0'||c>'9'){
if(c=='-')f = -1;
c = getchar();
}
while(c>='0'&&c<='9')k = k * 10 + c - '0' , c = getchar();
return k * f;
}
void out(__int128 x){
if(x<0)putchar('-') , x = -x;
if(x<10)putchar(x+'0');
else out(x/10) , putchar(x%10+'0');
}
void ex_gcd(__int128 a , __int128 b , __int128& x , __int128& y){
if(!b){
x = 1;
y = 0;
}else{
ex_gcd(b,a%b,y,x);
y -= a / b * x;
}
}
__int128 inverse(__int128 a , __int128 m){
__int128 x , y;
ex_gcd(a,m,x,y);
return (x % m + m) % m;
}
__int128 CRT(){
__int128 suma = 1;
for(__int128 i=1;i<=n;i++)suma *= a[i];
for(__int128 i=1;i<=n;i++){
__int128 m = suma / a[i];
c[i] = m * inverse(m,a[i]);
}
__int128 ans = 0;
for(__int128 i=1;i<=n;i++)ans += c[i] * b[i] , ans %= suma;
return ans;
}
最大流
点击查看代码
int dis[40005] , flow[4000005] , cnt , head[40005] , s , t = 40001;
int n , m , cur[40005] , k , sum;
struct edge{
int to , nxt , mxfl;
}ed[4000005];
void init(){
memset(head,-1,sizeof(head));
cnt = 0;
}
void add_edge(int u , int v , int w){
ed[cnt].to = v , ed[cnt].nxt = head[u] , ed[cnt].mxfl = w , head[u] = cnt , cnt++;
ed[cnt].to = u , ed[cnt].nxt = head[v] , ed[cnt].mxfl = 0 , head[v] = cnt , cnt++;
}
bool bfs(){
memset(dis,0,sizeof(dis));
queue<int> q;q.push(s);dis[s]=1;
while(!q.empty()){
int u = q.front();q.pop();
for(int i=head[u];~i;i=ed[i].nxt){
int v = ed[i].to;
if(!dis[v]&&ed[i].mxfl>flow[i]){
dis[v] = dis[u] + 1;
q.push(v);
}
}
}
return dis[t] > 0;
}
int dfs(int u , int f){
if(u==t)return f;
if(f==0)return 0;
int ret = 0;
for(int &i=cur[u];~i;i=ed[i].nxt){
int v = ed[i].to , d;
if(dis[v]==dis[u]+1&&(d=dfs(v,min(f-ret,ed[i].mxfl-flow[i])))){
ret += d , flow[i] += d , flow[i^1] -= d;
if(ret==f)return ret;
}
}
return ret;
}
int dinic(){
int maxflow = 0;
while(bfs()){
memcpy(cur,head,sizeof(head));
maxflow += dfs(s,1e18);
}
return maxflow;
}
最小费用最大流
点击查看代码
int n , m , tot = 1 , lnk[N] , cur[N] , ter[M] , nxt[M] , cap[M] , cost[M] , dis[N] , ret;
bool vis[N];
void add(int u, int v, int w, int c) {
ter[++tot] = v , nxt[tot] = lnk[u] , lnk[u] = tot , cap[tot] = w , cost[tot] = c;
}
void addedge(int u , int v , int w , int c){add(u,v,w,c) , add(v,u,0,-c);}
bool spfa(int s, int t){
memset(dis,0x3f,sizeof(dis));
memcpy(cur,lnk,sizeof(lnk));
std::queue<int> q;
q.push(s) , dis[s] = 0 , vis[s] = true;
while(!q.empty()){
int u = q.front();
q.pop() , vis[u] = false;
for(int i=lnk[u];i;i=nxt[i]){
int v = ter[i];
if(cap[i]&&dis[v]>dis[u]+cost[i]){
dis[v] = dis[u] + cost[i];
if(!vis[v])q.push(v) , vis[v] = true;
}
}
}
return dis[t] != INF;
}
int dfs(int u , int t , int flow){
if(u==t)return flow;
vis[u] = true;
int ans = 0;
for(int &i=cur[u];i&&ans<flow;i=nxt[i]){
int v = ter[i];
if(!vis[v]&&cap[i]&&dis[v]==dis[u]+cost[i]){
int x = dfs(v,t,std::min(cap[i],flow-ans));
if(x)ret += x * cost[i] , cap[i] -= x , cap[i^1] += x , ans += x;
}
}
vis[u] = false;
return ans;
}
int mcmf(int s , int t){
int ans = 0;
while(spfa(s,t)){
int x;
while((x=dfs(s,t,INF)))ans += x;
}
return ans;
}
树状树组
点击查看代码
int bit[500005];
int lowbit(int x){
return x & (-x);
}
void add(int i , int x){
for(;i<=n;i+=lowbit(i))bit[i] += x;
}
int search(int x){
int ans = 0;
for(;x>0;x-=lowbit(x))ans += bit[x];
return ans;
}
KMP
点击查看代码
vector<int> work(string s){
int len = s.size();
vector<int> p(len);
for(int i=1,j=0;i<len;i++){
j = p[i-1];
while(j&&s[i]!=s[j])j = p[j-1];
if(s[i]==s[j])j++;
p[i] = j;
}
return p;
}
vector<int> KMP(){
string s = s2 + '#' + s1;
int l1 = s1.size() , l2 = s2.size();
vector<int> p = work(s) , ans;
for(int i=l2+1;i<=l1+l2;i++){
if(p[i]==l2)ans.push_back(i-2*l2);
}
return ans;
}
LCA
点击查看代码
int st[500005][19] , dfn[500005] , n , m , root , df;
vector<int> vec[500005];
int get(int x , int y){
return (dfn[x] < dfn[y] ? x : y);
}
void dfs(int u , int fa){
st[dfn[u]=++df][0] = fa;
for(int i=0;i<vec[u].size();i++){
if(vec[u][i]==fa)continue;
dfs(vec[u][i],u);
}
}
int lca(int u , int v){
if(u==v)return u;
if((u=dfn[u])>(v=dfn[v]))swap(u,v);
int d = __lg(v-u++);
return get(st[u][d],st[v-(1<<d)+1][d]);
}
void init(){
dfs(root,0);
for(int j=1;j<=__lg(n);j++){
for(int i=1;i+(1<<j)-1<=n;i++){
st[i][j] = get(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
}
tarjan求SCC
点击查看代码
int low[100005] , dfn[10005] , s[10005] , num[10005] , dfncnt;
int sc , sz[10005] , n , m , d[10005] , dp[10005] , tp , color[100005];
vector<int> g[10005] , vec[10005];
struct node{
int u , v;
};
vector<node> edge;
bool in_stack[10005];
void tarjan(int u){
low[u] = dfn[u] = ++dfncnt , s[++tp] = u , in_stack[u] = 1;
for(int i=0;i<g[u].size();i++){
int v = g[u][i];
if(!dfn[v]){
tarjan(v);
low[u] = min(low[u],low[v]);
}else if(in_stack[v]){
low[u] = min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){
++sc;
do{
color[s[tp]] = sc;
sz[sc]++;
in_stack[s[tp]] = 0;
}while(s[tp--]!=u);
}
}
树剖
点击查看代码
int n , m , dep[200005] , siz[200005] , son[200005] , dfn[200005] , dfncnt , fa[200005];
int w[200005] , top[200005] , rnk[200005];
vector<pair<int,int> > vec[200005] , edge;
void dfs1(int u , int f){
fa[u] = f , dep[u] = dep[f] + 1 , siz[u] = 1;
for(pair<int,int> ed:vec[u]){
int v = ed.first;
if(v==f)continue;
w[v] = ed.second;
dfs1(v,u);
siz[u] += siz[v];
if(siz[son[u]]<siz[v])son[u] = v;
}
}
void dfs2(int u , int tp){
top[u] = tp , dfn[u] = ++dfncnt , rnk[dfncnt] = u;
if(son[u])dfs2(son[u],tp);
for(pair<int,int> ed:vec[u]){
int v = ed.first;
if(v!=fa[u]&&v!=son[u])dfs2(v,v);
}
}
void solve_change(int u , int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
add(1,dfn[top[u]],dfn[u]);
u = fa[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
add(1,dfn[v]+1,dfn[u]);
}
int solve_sum(int u , int v){
int sum = 0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
sum += query_sum(1,dfn[top[u]],dfn[u]);
u = fa[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
sum += query_sum(1,dfn[v]+1,dfn[u]);
return sum;
}
tarjan求割点
点击查看代码
int n , m;
int dfn[100005] , low[100005] , idx , res;
bool vis[100005] , flag[100005];
vector<int> edge[100005];
void tarjan(int u , int fa){
dfn[u] = low[u] = ++idx , vis[u] = true;
int child = 0;
for(int v:edge[u]){
if(!vis[v]){
child++;
tarjan(v,u);
low[u] = min(low[u],low[v]);
if(fa!=u&&low[v]>=dfn[u]&&!flag[u]){
flag[u] = true , res++;
}
}else if(v!=fa){
low[u] = min(low[u],dfn[v]);
}
}
if(fa==u&&child>=2&&!flag[u]){
flag[u] = true , res++;
}
}
manacher
点击查看代码
void manacher(string s){
string s2 = "#";
for(int i=0;i<n;i++)s2 += s[i] , s2 += "#";
n = s2.size();
for(int i=0,l=0,r=-1;i<n;i++){
int k = (i > r) ? 1 : min(d[l+r-i],r-i+1);
while(i-k>=0&&i+k<n&&s2[i-k]==s2[i+k])k++;
d[i] = k--;
if(i+k>r)r = i + k , l = i - k;
}
for(int i=0;i<n;i++)ansn = max(ansn,d[i]);
}
后缀排序
点击查看代码
void sort_sa(){
for(int i=1;i<=n;i++)cnt[rk[i]=s[i]]++;
for(int i=1;i<=m;i++)cnt[i] += cnt[i-1];
for(int i=n;i>=1;i--)sa[cnt[rk[i]]--] = i;
for(int w=1;;w<<=1,m=p){
int cur = 0;
for(int i=n-w+1;i<=n;i++)id[++cur] = i;
for(int i=1;i<=n;i++)if(sa[i]>w)id[++cur] = sa[i] - w;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)cnt[rk[i]]++;
for(int i=1;i<=m;i++)cnt[i] += cnt[i-1];
for(int i=n;i>=1;i--)sa[cnt[rk[id[i]]]--] = id[i];
p = 0;
memcpy(oldrk,rk,sizeof(oldrk));
for(int i=1;i<=n;i++){
if(oldrk[sa[i]]==oldrk[sa[i-1]]&&oldrk[sa[i]+w]==oldrk[sa[i-1]+w])rk[sa[i]] = p;
else rk[sa[i]] = ++p;
}
if(p==n)break;
}
}
线性基
点击查看代码
int a[60];
void add(int x){
for(int i=60;~i;i--){
if((x>>i)&1){
if(!a[i]){
a[i] = x;
return;
}else x ^= a[i];
}
}
}
int query(){
int x = 0;
for(int i=60;~i;i--){
x = max(x,x^a[i]);
}
return x;
}
李超线段树
点击查看代码
double eps = 1e-9;
int cmp(double x , double y){
if(x-y>eps)return 1;
if(y-x>eps)return -1;
return 0;
}
struct line{
double k , b;
}p[100005];
int s[160005] , cnt;
double calc(int id , int d){
return p[id].b + p[id].k * d;
}
void add(int x0 , int y0 , int x1 , int y1){
cnt++;
if(x0==x1)p[cnt].k = 0 , p[cnt].b = max(y0,y1);
else p[cnt].k = 1.0 * (y1 - y0) / (x1 - x0) , p[cnt].b = y0 - p[cnt].k * x0;
}
void upd(int root , int cl , int cr , int u){
int &v = s[root] , mid = (cl + cr) >> 1;
int bmid = cmp(calc(u,mid),calc(v,mid));
if(bmid==1||(!bmid&&u<v))swap(u,v);
int bl = cmp(calc(u,cl),calc(v,cl)) , br = cmp(calc(u,cr),calc(v,cr));
if(bl==1||(!bl&&u<v))upd(root<<1,cl,mid,u);
if(br==1||(!br&&u<v))upd(root<<1|1,mid+1,cr,u);
}
void update(int root , int cl , int cr , int l , int r , int u){
if(l<=cl&&cr<=r){
upd(root,cl,cr,u);
return;
}
int mid = (cl + cr) >> 1;
if(l<=mid)update(root<<1,cl,mid,l,r,u);
if(mid<r)update(root<<1|1,mid+1,cr,l,r,u);
}
pair<double,int> pmax(pair<double,int> x , pair<double,int> y){
if(cmp(x.first,y.first)==-1)return y;
else if(cmp(x.first,y.first)==1)return x;
else return x.second < y.second ? x : y;
}
pair<double,int> query(int root , int l , int r , int d){
if(r<d||d<l)return {0,0};
int mid = (l + r) >> 1;
double res = calc(s[root],d);
if(l==r)return {res,s[root]};
return pmax({res,s[root]},pmax(query(root<<1,l,mid,d),query(root<<1|1,mid+1,r,d)));
}
动态开点线段树+线段树合并
点击查看代码
struct segtree{
int l , r , ls , rs , num , maxid;
};
vector<segtree> tree;
segtree push_up(int i){
segtree s = {tree[i].l,tree[i].r,tree[i].ls,tree[i].rs,0,0};
if(tree[i].ls){
if(tree[tree[i].ls].num>s.num)s.maxid = tree[tree[i].ls].maxid;
s.num = max(s.num,tree[tree[i].ls].num);
}
if(tree[i].rs){
if(tree[tree[i].rs].num>s.num)s.maxid = tree[tree[i].rs].maxid;
s.num = max(s.num,tree[tree[i].rs].num);
}
return s;
}
void update(int i , int x , int k){
if(tree[i].l==tree[i].r){
tree[i].num += k , tree[i].maxid = tree[i].l;
return;
}
int mid = (tree[i].l + tree[i].r) >> 1;
if(mid>=x){
if(!tree[i].ls){
tree.push_back({tree[i].l,mid,0,0,0,0});
tree[i].ls = tree.size() - 1;
}
update(tree[i].ls,x,k);
}else{
if(!tree[i].rs){
tree.push_back({mid+1,tree[i].r,0,0,0,0});
tree[i].rs = tree.size() - 1;
}
update(tree[i].rs,x,k);
}
tree[i] = push_up(i);
}
int merge(int i1 , int i2){
if(!i1)return i2;
if(!i2)return i1;
if(tree[i1].l==tree[i1].r){
tree[i1].num += tree[i2].num , tree[i1].maxid = tree[i1].l;
return i1;
}
tree[i1].ls = merge(tree[i1].ls,tree[i2].ls);
tree[i1].rs = merge(tree[i1].rs,tree[i2].rs);
tree[i1] = push_up(i1);
return i1;
}
HLPP(最大流)
点击查看代码
struct qxx{
int nex , t;
long long v;
}e[240005];
int h[1205] , cnt = 1;
void add_path(int f , int t , long long w){
e[++cnt] = {h[f],t,w} , h[f] = cnt;
}
void add_flow(int f , int t , long long v){
add_path(f,t,v) , add_path(t,f,0);
}
int ht[1205];
long long ex[1205];
int gap[1205];
stack<int> B[1205];
int level = 0;
int push(int u){
bool init = u == s;
for(int i=h[u];i;i=e[i].nex){
const int &v = e[i].t;const long long &w = e[i].v;
if(!w||(init==false&&ht[u]!=ht[v]+1)||ht[v]==INF)continue;
long long k = init ? w : min(w,ex[u]);
if(v!=s&&v!=t&&!ex[v])B[ht[v]].push(v) , level = max(level,ht[v]);
ex[u] -= k , ex[v] += k , e[i].v -= k , e[i^1].v += k;
if(!ex[u])return 0;
}
return 1;
}
void relabel(int u){
ht[u] = INF;
for(int i=h[u];i;i=e[i].nex)if(e[i].v)ht[u] = min(ht[u],ht[e[i].t]);
if(++ht[u]<n){
B[ht[u]].push(u);
level = max(level,ht[u]);
++gap[ht[u]];
}
}
bool bfs_init(){
memset(ht,0x3f,sizeof(ht));
queue<int> q;
q.push(t) , ht[t] = 0;
while(q.size()){
int u = q.front();
q.pop();
for(int i=h[u];i;i=e[i].nex){
const int &v = e[i].t;
if(e[i^1].v&&ht[v]>ht[u]+1)ht[v] = ht[u] + 1 , q.push(v);
}
}
return ht[s] != INF;
}
int select(){
while(level>-1&&B[level].size()==0)level--;
return level == -1 ? 0 : B[level].top();
}
long long hlpp(){
if(!bfs_init())return 0;
memset(gap,0,sizeof(gap));
for(int i=1;i<=n;i++)if(ht[i]!=INF)gap[ht[i]]++;
ht[s] = n;
push(s);
int u;
while((u=select())){
B[level].pop();
if(push(u)){
if(!--gap[ht[u]]){
for(int i=1;i<=n;i++){
if(i!=s&&ht[i]>ht[u]&&ht[i]<n+1)ht[i] = n + 1;
}
}
relabel(u);
}
}
return ex[t];
}
笛卡尔树
点击查看代码
int w[10000005] , stk[10000005] , k , n , top;
int ls[10000005] , rs[10000005];
void build(){
for(int i=1;i<=n;i++){
int k = top;
while(k>0&&w[stk[k]]>w[i])k--;
if(k)rs[stk[k]] = i;
if(k<top)ls[i] = stk[k+1];
stk[++k] = i;
top = k;
}
}
吉司机线段树(支持历史最值,不支持取max)
点击查看代码
struct segment{
int l , r , sum , se , cnt , maxa , maxb;
int add1 , add2 , add3 , add4;
}tree[2000005];
int n , m;
void push_up(int i){
tree[i].sum = tree[i<<1].sum + tree[i<<1|1].sum , tree[i].maxa = max(tree[i<<1].maxa,tree[i<<1|1].maxa);
tree[i].maxb = max(tree[i<<1].maxb,tree[i<<1|1].maxb);
if(tree[i<<1].maxa==tree[i<<1|1].maxa){
tree[i].cnt = tree[i<<1].cnt + tree[i<<1|1].cnt , tree[i].se = max(tree[i<<1].se,tree[i<<1|1].se);
}else if(tree[i<<1].maxa>tree[i<<1|1].maxa){
tree[i].cnt = tree[i<<1].cnt , tree[i].se = max(tree[i<<1].se,tree[i<<1|1].maxa);
}else{
tree[i].cnt = tree[i<<1|1].cnt , tree[i].se = max(tree[i<<1|1].se,tree[i<<1].maxa);
}
}
void change(int i , int k1 , int k2 , int k3 , int k4){
tree[i].sum += k1 * tree[i].cnt + k2 * (tree[i].r - tree[i].l + 1 - tree[i].cnt);
tree[i].maxb = max(tree[i].maxb,tree[i].maxa+k3) , tree[i].maxa += k1;
if(tree[i].se!=-2e9)tree[i].se += k2;
tree[i].add3 = max(tree[i].add1+k3,tree[i].add3);
tree[i].add4 = max(tree[i].add2+k4,tree[i].add4);
tree[i].add1 += k1 , tree[i].add2 += k2;
}
void push_down(int i){
int maxn = max(tree[i<<1].maxa,tree[i<<1|1].maxa);
if(tree[i<<1].maxa==maxn)change(i<<1,tree[i].add1,tree[i].add2,tree[i].add3,tree[i].add4);
else change(i<<1,tree[i].add2,tree[i].add2,tree[i].add4,tree[i].add4);
if(tree[i<<1|1].maxa==maxn)change(i<<1|1,tree[i].add1,tree[i].add2,tree[i].add3,tree[i].add4);
else change(i<<1|1,tree[i].add2,tree[i].add2,tree[i].add4,tree[i].add4);
tree[i].add1 = tree[i].add2 = tree[i].add3 = tree[i].add4 = 0;
}
void build(int i , int l , int r){
tree[i].l = l , tree[i].r = r;
if(l==r){
cin >> tree[i].sum;tree[i].maxa = tree[i].maxb = tree[i].sum;
tree[i].se = -2e9 , tree[i].cnt = 1;
return;
}
int mid = (l + r) >> 1;
build(i<<1,l,mid) , build(i<<1|1,mid+1,r);
push_up(i);
}
void update_add(int i , int l , int r , int k){
if(tree[i].l>=l&&tree[i].r<=r){
tree[i].sum += (tree[i].r - tree[i].l + 1) * k , tree[i].maxa += k , tree[i].maxb = max(tree[i].maxa,tree[i].maxb);
if(tree[i].se!=-2e9)tree[i].se += k;
tree[i].add1 += k , tree[i].add2 += k;
tree[i].add3 = max(tree[i].add3,tree[i].add1) , tree[i].add4 = max(tree[i].add4,tree[i].add2);
return;
}
push_down(i);
if(tree[i<<1].r>=l)update_add(i<<1,l,r,k);
if(tree[i<<1|1].l<=r)update_add(i<<1|1,l,r,k);
push_up(i);
}
void update_min(int i , int l , int r , int k){
if(tree[i].maxa<=k)return;
else if(k>tree[i].se&&tree[i].l>=l&&tree[i].r<=r){
tree[i].sum -= (tree[i].maxa - k) * tree[i].cnt;
tree[i].add1 -= (tree[i].maxa - k) , tree[i].maxa = k;
}else{
push_down(i);
if(tree[i<<1].r>=l)update_min(i<<1,l,r,k);
if(tree[i<<1|1].l<=r)update_min(i<<1|1,l,r,k);
push_up(i);
}
}
int query_sum(int i , int l , int r){
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].sum;
push_down(i);int sum = 0;
if(tree[i<<1].r>=l)sum += query_sum(i<<1,l,r);
if(tree[i<<1|1].l<=r)sum += query_sum(i<<1|1,l,r);
return sum;
}
int query_maxa(int i , int l , int r){
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].maxa;
push_down(i);int sum = -2e9;
if(tree[i<<1].r>=l)sum = max(sum,query_maxa(i<<1,l,r));
if(tree[i<<1|1].l<=r)sum = max(sum,query_maxa(i<<1|1,l,r));
return sum;
}
int query_maxb(int i , int l , int r){
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].maxb;
push_down(i);int sum = -2e9;
if(tree[i<<1].r>=l)sum = max(sum,query_maxb(i<<1,l,r));
if(tree[i<<1|1].l<=r)sum = max(sum,query_maxb(i<<1|1,l,r));
return sum;
}
逆元(\(n\) 个任意数)
点击查看代码
int n, p, k, a[MAXN];
int s[MAXN], t[MAXN];
int qpow(int a , int b){
if(!b){
return 1;
}
int c = qpow(a,b/2);
c = 1ll * c * c % p;
if(b%2){
c = 1ll * c * a % p;
}
return c;
}
void init(){
s[0] = 1;
for(int i=1;i<=n;++i){
s[i] = 1ll * s[i-1] * a[i] % p;
}
t[n] = qpow(s[n],p-2);
for(int i=n-1;i>=1;--i){
t[i] = 1ll * t[i+1] * a[i+1] % p;
}
int powk = 1, ans = 0;
for(int i=1;i<=n;++i){
powk = 1ll * powk * k % p;
ans = (ans + 1ll * powk * s[i-1] % p * t[i]) % p;
}
}
可持久化线段树(静态区间第 \(k\) 小)
点击查看代码
struct tree{
int l , r , sum , ls , rs;
}tree[200005<<5];
int build(int l , int r){
int id = ++tot;
tree[id] = {l,r,0};
if(l==r)return id;
int mid = (l + r) >> 1;
tree[id].ls = build(l,mid) , tree[id].rs = build(mid+1,r);
return id;
}
int update(int i , int k){
int id = ++tot;
tree[id] = tree[i] , tree[id].sum++;
if(tree[i].l==tree[i].r)return id;
if(tree[tree[i].ls].r>=k)tree[id].ls = update(tree[i].ls,k);
else tree[id].rs = update(tree[i].rs,k);
return id;
}
int query(int u , int v , int k){
if(tree[u].l==tree[u].r)return tree[u].l;
int x = tree[tree[u].ls].sum - tree[tree[v].ls].sum;
if(k<=x)return query(tree[u].ls,tree[v].ls,k);
else return query(tree[u].rs,tree[v].rs,k-x);
}
可持久化线段树(支持插入,删除,全局第 \(k\) 小,\(x\) 的排名,\(x\) 的前驱后继)
点击查看代码
struct tree{
int l , r , sum , ls , rs;
}tree[500005<<5];
struct query{
int op , id , x;
}q[500005];
int build(int l , int r){
int id = ++tot;
tree[id] = {l,r,0};
if(l==r){
if(l==1)tree[id].sum = 1;
else if(l==len)tree[id].sum = 1;
return id;
}
int mid = (l + r) >> 1;
tree[id].ls = build(l,mid) , tree[id].rs = build(mid+1,r);
tree[id].sum = tree[tree[id].ls].sum + tree[tree[id].rs].sum;
return id;
}
int update_add(int i , int k){
int id = ++tot;
tree[id] = tree[i] , tree[id].sum++;
if(tree[i].l==tree[i].r)return id;
if(tree[tree[i].ls].r>=k)tree[id].ls = update_add(tree[i].ls,k);
else tree[id].rs = update_add(tree[i].rs,k);
return id;
}
int update_del(int i , int k){
int id = ++tot;
tree[id] = tree[i];
if(tree[i].l==tree[i].r){
if(tree[id].sum>0)tree[id].sum--;
return id;
}
if(tree[tree[i].ls].r>=k)tree[id].ls = update_del(tree[i].ls,k);
else tree[id].rs = update_del(tree[i].rs,k);
tree[id].sum = tree[tree[id].ls].sum + tree[tree[id].rs].sum;
return id;
}
int query_kth(int u , int k){
if(tree[u].l==tree[u].r)return tree[u].l;
int x = tree[tree[u].ls].sum;
if(k<=x)return query_kth(tree[u].ls,k);
else return query_kth(tree[u].rs,k-x);
}
int query_x(int i , int l , int r){
if(l>r)return 0;
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].sum;
int sum = 0;
if(tree[tree[i].ls].r>=l)sum += query_x(tree[i].ls,l,r);
if(tree[tree[i].rs].l<=r)sum += query_x(tree[i].rs,l,r);
return sum;
}
int get_x(int id , int x){
return query_x(rt[id],1,x-1);
}
int get_minx(int id , int x){
int nth = get_x(id,x);
return query_kth(rt[id],nth);
}
int get_maxx(int id , int x){
int nth = get_x(id,x);
return query_kth(rt[id],nth+1);
}
无源汇上下界可行流的建图部分
点击查看代码
for(int i=1;i<=m;i++){
int u , v , r;cin >> u >> v >> l[i] >> r;
add_edge(u,v,r-l[i]);
id[i] = cnt , d[u] -= l[i] , d[v] += l[i];
}
int sum = 0;
for(int i=1;i<=n;i++){
if(d[i]>0){
add_edge(s,i,d[i]);
sum += d[i];
}else if(d[i]<0){
add_edge(i,t,-d[i]);
}
}
int ans = dinic();
if(ans<sum){
cout << "No";
return 0;
}
cout << "Yes\n";
for(int i=1;i<=m;i++)cout << flow[id[i]^1] + l[i] << "\n";
矩阵快速幂
点击查看代码
struct node{
int n , m , a[105][105];
node operator * (const node &b)const{
node re;re.n = n , re.m = b.m;
for(int i=1;i<=re.n;i++){
for(int j=1;j<=re.m;j++){
re.a[i][j] = 0;
for(int k=1;k<=m;k++)re.a[i][j] += a[i][k] * b.a[k][j] , re.a[i][j] %= mod;
}
}
return re;
}
}a , b;
int k;
node qpow(node x , int y){
node ans;
ans.n = x.n , ans.m = x.m;
for(int i=1;i<=ans.n;i++){
for(int j=1;j<=ans.m;j++)ans.a[i][j] = (i == j);
}
for(;y;y>>=1,x=x*x){
if(y&1)ans = ans * x;
}
return ans;
}
线段树合并与分裂
点击查看代码
struct segtree{
int l , r , ls , rs , num;
};
vector<segtree> tree;
segtree push_up(int i){
segtree s = {tree[i].l,tree[i].r,tree[i].ls,tree[i].rs,0};
if(tree[i].ls)s.num += tree[tree[i].ls].num;
if(tree[i].rs)s.num += tree[tree[i].rs].num;
return s;
}
int build(int l , int r){
tree.push_back({l,r,0,0,0});
int i = tree.size() - 1;
if(l==r){
tree[i].num = a[l];
return i;
}
int mid = (l + r) >> 1;
tree[i].ls = build(l,mid) , tree[i].rs = build(mid+1,r);
tree[i] = push_up(i);
return i;
}
//区间加
void update(int i , int x , int k){
if(tree[i].l==tree[i].r){
tree[i].num += k;
return;
}
int mid = (tree[i].l + tree[i].r) >> 1;
if(mid>=x){
if(!tree[i].ls){
tree.push_back({tree[i].l,mid,0,0,0});
tree[i].ls = tree.size() - 1;
}
update(tree[i].ls,x,k);
}else{
if(!tree[i].rs){
tree.push_back({mid+1,tree[i].r,0,0,0});
tree[i].rs = tree.size() - 1;
}
update(tree[i].rs,x,k);
}
tree[i] = push_up(i);
}
//合并
int merge(int i1 , int i2){
if(!i1)return i2;
if(!i2)return i1;
if(tree[i1].l==tree[i1].r){
tree[i1].num += tree[i2].num;
return i1;
}
tree[i1].ls = merge(tree[i1].ls,tree[i2].ls);
tree[i1].rs = merge(tree[i1].rs,tree[i2].rs);
tree[i1] = push_up(i1);
return i1;
}
//分裂出[x,y]
void split(int &p , int &q , int x , int y){
if(!p||x>tree[p].r||y<tree[p].l)return;
if(x<=tree[p].l&&y>=tree[p].r){
q = p , p = 0;
return;
}
if(!q){
tree.push_back({tree[p].l,tree[p].r,0,0,0});
q = tree.size() - 1;
}
int mid = (tree[p].l + tree[p].r) >> 1;
if(tree[p].ls)split(tree[p].ls,tree[q].ls,x,y);
if(tree[p].rs)split(tree[p].rs,tree[q].rs,x,y);
tree[p] = push_up(p) , tree[q] = push_up(q);
}
int query(int i , int l , int r){
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].num;
int sum = 0;
if(tree[i].ls&&tree[tree[i].ls].r>=l)sum += query(tree[i].ls,l,r);
if(tree[i].rs&&tree[tree[i].rs].l<=r)sum += query(tree[i].rs,l,r);
return sum;
}
int get_kth(int i , int k){
if(tree[i].l==tree[i].r)return tree[i].l;
if(k<=tree[tree[i].ls].num)return get_kth(tree[i].ls,k);
else if(k<=tree[i].num)return get_kth(tree[i].rs,k-tree[tree[i].ls].num);
else return -1;
}