板子

算法枚举

  • DP,贪心,二分
  • 核心:找规律,观察性质
  • 套 DS : 扫描线,线段树,BIT,平衡树?堆,单调栈/队列

技巧枚举

  • 正难则反,根号分治,前后考虑,拆贡献,转化

字符串

KMP

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define in inline
#define pb push_back
const int N = 1e6+10;

ll read(){
	ll x = 0,f = 1;char c = getchar();
	for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
	for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
	return x * f;
}


char a[N],b[N];
int nx[N],p[N],l1,l2;
vector<int>ans;

int main(){
	scanf("%s%s",a + 1,b + 1);
	l1 = strlen(a + 1),l2 = strlen(b + 1);
	for(int i = 2,j = 0;i <= l2;i++){
		while(j > 0 && b[i] != b[j+1])j = nx[j];
		if(b[i] == b[j+1])j++;
		nx[i] = j;
	}
	for(int i = 1,j = 0;i <= l1;i++){
		while(j > 0 && a[i] != b[j+1])j = nx[j];
		if(a[i] == b[j+1])j++;
		if(j == l2)ans.pb(i - l2 + 1);//匹配节点
	}
	for(int x : ans)printf("%d\n",x);
	for(int i = 1;i <= l2;i++)printf("%d ",nx[i]);//border
	
	
	return 0;
}

后缀数组

int n,m,p;
char c[N]; 
int sa[N],rk[N],ork[N<<1],id[N],cnt[N];
bool cmp(int a,int b,int w){return ork[a] == ork[b] && ork[a + w] == ork[b + w];}
//若与相等的不加,否则加
int main(){
	scanf("%s",c+1);
	n = strlen(c+1),m = 128;
	for(int i = 1;i <= n;i++)cnt[rk[i] = c[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,p = 0){
		for(int i = n - w + 1;i <= n;i++)id[++p] = i;
		for(int i = 1;i <= n;i++)
			if(sa[i] > w)id[++p] = 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(ork,rk,sizeof rk);
		for(int i = 1;i <= n;i++)rk[sa[i]] = cmp(sa[i-1],sa[i],w) ? p : ++p;
		if(p == n)break;
	}
	for(int i = 1;i <= n;i++){
		if(p)p--;
		while(c[i + p] == c[sa[rk[i] - 1] + p])p++;
		ht[rk[i]] = p;
	}
	for(int i = 1;i <= n;i++)printf("%d ",sa[i]);
	printf("\n");

	return 0;

}

数学

\(\mathcal{O}(1)\) 龟速乘

ll mul(ll x,ll y,ll p){return (x*y-(ll)(x/(long double)p*y+1e-3)*p+p) % p;}

三分

int n;
double a[N],b[N],c[N];
double f(double x){
	double ans = -1e8;
	for(int i = 1;i <= n;i++)ans = max(ans,a[i] * x * x + b[i] * x + c[i]);
	return ans;
}
void solve(){
	n = read();
	for(int i = 1;i <= n;i++)a[i] = read(),b[i] = read(),c[i] = read();
	double l = 0,r = 1000;
	while(l + eps < r){
		double mid1 = (l + r) / 2.0;
		double mid2 = (mid1 + r) / 2.0;
		if(f(mid1) + eps < f(mid2))r = mid2;
		else l = mid1;
	}
	printf("%.4lf\n",f(l));
}
int main(){
	int t = read();
	while(t--)solve();
	return 0;
}



扩展欧拉定理

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<ll,ll>
#define fi first
#define se second
#define pb push_back
const int N = 2e5+10;

ll read(){
	ll x = 0,f = 1;char c = getchar();
	for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
	for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
	return x * f;
}

ll n,p,m;
ll phi(ll x){
	if(x == 1)return 1;
	ll ans = x;
	for(ll i = 2;i <= sqrt(x);i++){
		if(x % i == 0){
			ans = ans / i * (i - 1);
			while(x % i == 0)x /= i;
		}
	}
	if(x > 1)ans = ans / x * (x - 1);
	return ans;
}

ll ksm(ll x,ll y){
	ll ans = 1;
	while(y){
		if(y & 1)ans = ans * x % p;
		x = x * x % p,y >>= 1;
	}return ans;
}
int main(){
	n = read(),p = read();
	ll p2 = phi(p);
	char c = getchar();
	bool f = 0;
	for(;c >= '0' && c <= '9';c = getchar()){
		m = (m<<1) + (m<<3) + c-'0';
		if(m >= p2)f = 1,m %= p2;
	}
	printf("%lld\n",ksm(n,m + f * p2));
	
	return 0;
}

拉格朗日插值

\(f(x) = \sum\limits_{i=1}^n y_i \prod\limits_{i \not = j} {\dfrac {x - x_j} {x_i - x_j}}\)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define in inline
#define se second
#define mp make_pair
#define pb push_back
const int N = 2e3+10;
const ll mod = 998244353;

ll read(){
	ll x = 0,f = 1;char c = getchar();
	for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
	for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
	return x * f;
}

int n;
ll x[N],y[N],k;

ll ksm(ll x,ll y){
	ll ans = 1;
	while(y){
		if(y & 1)ans = ans * x % mod;
		x = x * x % mod,y >>= 1;
	}return ans;
}
int main(){
	n = read(),k = read();
	for(int i = 1;i <= n;i++)x[i] = read(),y[i] = read();
	ll ans = 0;
	for(int i = 1;i <= n;i++){
		ll s = y[i] % mod;
		for(int j = 1;j <= n;j++){
			if(i == j)continue;
			s = s * (k - x[j] + mod) % mod;
			s = s * ksm((x[i] - x[j] + mod) % mod,mod - 2) % mod;
		}
		(ans += s) %= mod;
	}
	printf("%lld\n",ans);

	return 0;

}

线性筛

void pre(int n){
	for(int i = 2;i <= n;i++){
		if(!v[i])p[++cnt] = i;
		for(int j = 1;j <= cnt && i <= n / p[j];j++){
			v[i * p[j]] = 1;
			if(i % p[j] == 0)break;
		}
	}
}

中国剩余定理

int n;
ll a[N],b[N];
void exgcd(ll a,ll b,ll &x,ll &y){
    if(b == 0){return x = 1,y = 0,void();}
    exgcd(b,a%b,y,x);
    y -= a / b * x;
} 
ll mul(ll x,ll y,ll p){return (x*y-(ll)(x/(long double)p*y+1e-3)*p+p) % p;}
ll lcm(ll x,ll y){return x / __gcd(x,y) * y;}
ll EXCRT(){
    ll x = a[1],M = b[1],k = 0,y = 0;
    F(i,2,n){
        ll gc = __gcd(M,b[i]);
        if((a[i]-x) % gc != 0)return -1;//无解
        exgcd(M,b[i],k,y);
        ll mod = b[i] / gc;
        k = (mul(k,(a[i] - x) / gc,mod) + mod) % mod;
        x = x + k * M;
        M = lcm(M,b[i]);
    }//EXCRT
    return x;
}
int main(){
    n = read();
    F(i,1,n)b[i] = read(),a[i] = read();
    printf("%lld\n",EXCRT());

    return cerr<<endl<<"Time:"<<clock()<<"ms"<<endl,0;

}

高斯消元

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define in inline
#define re register
#define pii pair<int,int>
#define fi first 
#define se second
#define pb(x) push_back(x)
#define D(i,a,b) for(re long double i = a;i >= b;i--)
#define F(i,a,b) for(re long long i = a;i <= b;i++)
const int N = 110;
const ll inf = 1e17;

ll read(){
    ll x = 0,f = 1;char c = getchar();
    for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
    for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
    return x * f;
}

int n;
db a[N][N],b[N];
int main(){
//    freopen("zfx.in","r",stdin);
//    freopen("zfx.out","w",stdout);
    n = read();
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++)a[i][j] = read();
        b[i] = read();
    }
    for(int i = 1;i <= n;i++){
        int k = i;
        for(int j = i+1;j <= n;j++)
            if(fabs(a[j][i]) > fabs(a[k][i]))k = j;
        for(int j = 1;j <= n;j++)swap(a[i][j],a[k][j]);swap(b[i],b[k]);
        if(fabs(a[i][i]) < 1e-8)return printf("No Solution\n"),0;
        db c = a[i][i];
        for(int j = 1;j <= n;j++)a[i][j] /= c;b[i] /= c;
        for(int j = 1;j <= n;j++){
            if(i == j)continue;
            db c = a[j][i];
            for(int k = i;k <= n;k++)a[j][k] -= c * a[i][k];
            b[j] -= c * b[i];
        } 
    }
    for(int i = 1;i <= n;i++){
       printf("%.2lf\n",b[i]); 
    }
    
    
	return cerr << "Time : " << clock() << " ms" << endl, 0;
}

图论

单源最短路径

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<ll,ll>
#define fi first
#define se second
#define pb push_back
const int N = 2e5+10;

ll read(){
	ll x = 0,f = 1;char c = getchar();
	for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
	for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
	return x * f;
}

int n,m,s;

vector<pii>e[N];
priority_queue<pii,vector<pii>,greater<pii> >q; 
ll d[N];
bool v[N];
void dij(int s){
	memset(v,0,sizeof v);
	for(int i = 1;i <= n;i++)d[i] = 1e17;
	d[s] = 0,q.push({0,s});
	while(!q.empty()){
		int x = q.top().se;q.pop();
		if(v[x])continue;
		v[x] = 1;
		for(auto it : e[x]){
			int y = it.fi;ll z = it.se;
			if(d[y] > d[x] + z){
				d[y] = d[x] + z;
				q.push({d[y],y});
			}
		}
	}
}

int main(){
	n = read(),m = read(),s = read();
	for(int i = 1;i <= m;i++){
		int x = read(),y = read();ll z = read();
		e[x].pb({y,z});
	}
	dij(s);
	for(int i = 1;i <= n;i++)printf("%lld ",d[i]);
	printf("\n");
	
	return 0;
}

欧拉路径

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
const int N = 2e5+10;

ll read(){
	ll x = 0,f = 1;char c = getchar();
	for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
	for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
	return x * f;
}

int n,m,rt;
int st[N],in[N],hd[N],top;
vector<int>e[N];

void dfs(int x){
	for(int &i = hd[x];i < (int)e[x].size();)dfs(e[x][i++]);
	st[++top] = x;//倒序
}

int main(){
	n = read(),m = read();
	for(int i = 1;i <= m;i++){
		int x = read(),y = read();
		e[x].pb(y),in[y]++;
	}
	for(int i = 1;i <= n;i++){
		sort(e[i].begin(),e[i].end());
		if(abs((int)e[i].size() - in[i]) > 1)return printf("No\n"),0;
		if(e[i].size() > in[i]){
			if(rt)return printf("No\n"),0;
			else rt = i;
		}//
	}
	dfs(rt ? rt : 1);
	if(top != m + 1)return printf("No\n"),0;
	for(int i = top;i >= 1;i--)printf("%d ",st[i]);
	
	return 0;
}

tarjan 缩点

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define in inline
#define pb push_back
const int N = 1e4+10;

ll read(){
	ll x = 0,f = 1;char c = getchar();
	for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
	for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
	return x * f;
}

int n,m;
int a[N];
vector<int>e[N],E[N];

int dfn[N],low[N],st[N],c[N],s[N];
int top,cnt,num;
bool v[N];

void tarjan(int x){
	dfn[x] = low[x] = ++cnt;
	st[++top] = x,v[x] = 1;
	for(int y : e[x]){
		if(!dfn[y])tarjan(y),low[x] = min(low[x],low[y]);
		else if(v[y])low[x] = min(low[x],dfn[y]);
	}
	if(dfn[x] == low[x]){
		int y = 0;num++;
		do{
			y = st[top--];
			v[y] = 0,c[y] = num,s[num] += a[y];
		}while(x != y);
	}
}

int f[N],ru[N],ans;
void topsort(){//
	queue<int>q;
	for(int i = 1;i <= num;i++)
		if(!ru[i])q.push(i),f[i] = s[i];
	while(!q.empty()){
		int x = q.front();q.pop();
		ans = max(ans,f[x]);
		for(int y : E[x]){
			f[y] = max(f[y],f[x] + s[y]);
			if(!(--ru[y]))q.push(y);
		}
	}
	printf("%d\n",ans);
}

map<pii,bool>mp;
int main(){
	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();
		e[x].pb(y);
	}
	for(int i = 1;i <= n;i++)
		if(!dfn[i])tarjan(i);//tarjan 
	for(int x = 1;x <= n;x++){
		for(int y : e[x]){
			if(c[x] == c[y])continue;
			if(!mp[{c[x],c[y]}])E[c[x]].pb(c[y]),ru[c[y]]++,mp[{c[x],c[y]}] = 1;
		}
	}//重建图 
	topsort();
	
	return 0;
}

点双

void tarjan(int x){
    low[x] = dfn[x] = ++cnt;
    int flag = 0;
    if(x == root && !hd[x])ans[++num].push_back(x);
    st[++top] = x;
    for(int i = hd[x];i;i = e[i].nx){
        int y = e[i].ver;
        if(!dfn[y]){
            tarjan(y);low[x] = min(low[x],low[y]);
            if(dfn[x] <= low[y]){
                num++;
                int p = 0;
                do{
                    p = st[top];top--;
                    ans[num].push_back(p);
                }while(p != y);
                ans[num].push_back(x);
            }
        }
        else low[x] = min(low[x],dfn[y]);
    }
}

数据结构

单调队列

P1886 滑动窗口 /【模板】单调队列

//19:02
int n,m;
int a[N],q[N],l = 1,r;
int main(){
	n = read(),m = read();
	for(int i = 1;i <= n;i++)a[i] = read();
	for(int i = 1;i <= n;i++){
		while(l <= r && q[l] < i - m + 1)l++;
		while(l <= r && a[i] <= a[q[r]])r--;
		q[++r] = i;
		if(i >= m)printf("%d ",a[q[l]]);
	}
	printf("\n");
	l = 1,r = 0;
	for(int i = 1;i <= n;i++){
		while(l <= r && q[l] < i - m + 1)l++;
		while(l <= r && a[i] >= a[q[r]])r--;
		q[++r] = i;
		if(i >= m)printf("%d ",a[q[l]]);
	}
	printf("\n");
	return 0;
}

ST 表

//19:14
int n,q;
int a[N],st[N][22];
int main(){
	n = read(),q = read();
	for(int i = 1;i <= n;i++)a[i] = read(),st[i][0] = a[i];
	for(int j = 1;j <= 20;j++)
		for(int i = 1;i + (1 << j) - 1 <= n;i++)st[i][j] = max(st[i][j-1],st[i + (1 << j - 1)][j-1]);
	for(int i = 1;i <= q;i++){
		int l = read(),r = read();
		int p = log2(r-l+1);
		printf("%d\n",max(st[l][p],st[r-(1<<p)+1][p]));
	}
	return 0;
}

线段树

P3373 【模板】线段树 2

//19:20
int n,q,mod;
int a[N];

struct segment{
	ll s[N<<2],la[N<<2],tag[N<<2];
	void pushup(int p){s[p] = (s[p<<1] + s[p<<1|1]) % mod;}
	void update(int p,ll k1,ll k2,int l,int r){
		s[p] = s[p] * k1 % mod + (ll)(r - l + 1) * k2 % mod;
		la[p] = la[p] * k1 % mod;
		tag[p] = (tag[p] * k1 % mod + k2) % mod;
	}
	void pushdown(int p,int l,int r){
		int mid = l + r >> 1;
		update(p<<1,la[p],tag[p],l,mid),update(p<<1|1,la[p],tag[p],mid+1,r);
		la[p] = 1,tag[p] = 0;
	}
	void build(int p,int l,int r){
		la[p] = 1;
		if(l == r)return s[p] = a[l],void();
		int mid = l + r >> 1;
		build(p<<1,l,mid),build(p<<1|1,mid+1,r);
		pushup(p);
	}
	void modify1(int p,int l,int r,int L,int R,ll k){
		if(L <= l && r <= R)return update(p,k,0,l,r),void();
		int mid = l + r >> 1;
		pushdown(p,l,r) ;
		if(L <= mid)modify1(p<<1,l,mid,L,R,k);
		if(R > mid)modify1(p<<1|1,mid+1,r,L,R,k);
		pushup(p);
	}
	void modify2(int p,int l,int r,int L,int R,ll k){
		if(L <= l && r <= R)return update(p,1,k,l,r),void();
		int mid = l + r >> 1;
		pushdown(p,l,r);
		if(L <= mid)modify2(p<<1,l,mid,L,R,k);
		if(R > mid)modify2(p<<1|1,mid+1,r,L,R,k);
		pushup(p);
	}
	ll ask(int p,int l,int r,int L,int R){
		if(L > r || R < l)return 0;
		if(L <= l && r <= R)return s[p];
		int mid = l + r >> 1;
		pushdown(p,l,r);
		return (ask(p<<1,l,mid,L,R) + ask(p<<1|1,mid+1,r,L,R)) % mod;
	}
}t;

int main(){
	n = read(),q = read(),mod = read();
	for(int i = 1;i <= n;i++)a[i] = read();
	t.build(1,1,n);
	for(int i = 1;i <= q;i++){
		int op = read(),l = read(),r = read();
		if(op == 1){
			ll k = read();
			t.modify1(1,1,n,l,r,k);
		}
		else if(op == 2){
			ll k = read();
			t.modify2(1,1,n,l,r,k);
		}
		else printf("%lld\n",t.ask(1,1,n,l,r));
	}
	
	return 0;
}

字典树

int n,q;
int s[N][110],sum[N],cnt = 1;
void add(char *ch){
	int len = strlen(ch),p = 1;
	for(int i = 0;i < len;i++){
		int c = ch[i] - 'a';
		if(ch[i] >= '0' && ch[i] <= '9')c = 26 + ch[i] - '0';
		if(ch[i] >= 'A' && ch[i] <= 'Z')c = 36 + ch[i] - 'A';
		if(!s[p][c])s[p][c] = ++cnt;
		p = s[p][c];
		sum[p]++;
	}
}
ll ask(char *ch){
	int len = strlen(ch),p = 1;
	for(int i = 0;i < len;i++){
		int c = ch[i] - 'a';
		if(ch[i] >= '0' && ch[i] <= '9')c = 26 + ch[i] - '0';
		if(ch[i] >= 'A' && ch[i] <= 'Z')c = 36 + ch[i] - 'A';
		if(!s[p][c])return 0;
		p = s[p][c];
	}
	return sum[p];
}
char c[N];
void solve(){
	n = read(),q = read();
	for(int i = 1;i <= n;i++){
		scanf("%s",c);
		add(c);
	}
	for(int i = 1;i <= q;i++){
		scanf("%s",c);
		printf("%lld\n",ask(c));
	}
	for(int i = 1;i <= cnt;i++)
		for(int j = 0;j < 100;j++)s[i][j] = 0,sum[i] = 0;
	cnt = 1;
}

李超树

struct line{
	db k,b = -inf;
	int id; 
	line(db k,db b,int id):k(k),b(b),id(id){}
	line(){}
	db val(int x){return k * x + b;}
};
bool cmp(line a,line b,int x){return (fabs(a.val(x) - b.val(x)) < eps) ? a.id < b.id : a.val(x) > b.val(x);}

struct LiChao_tree{
    line mx[N<<5];
    line ask(line a,line b,int x){return cmp(a,b,x) ? a : b;}
    void modify(int p,int l,int r,line x){
        if(l > r)return;
        int mid = l + r >> 1;
        if(cmp(x,mx[p],mid))swap(mx[p],x);
        if(cmp(x,mx[p],l))modify(p<<1,l,mid,x);
        if(cmp(x,mx[p],r))modify(p<<1|1,mid+1,r,x);
    }
    void modify(int p,int l,int r,int L,int R,line x){
        if(L <= l && r <= R)return modify(p,l,r,x),void();
        int mid = l + r >> 1;
        if(L <= mid)modify(p<<1,l,mid,L,R,x);
        if(R > mid)modify(p<<1|1,mid+1,r,L,R,x);
    }
    line query(int p,int l,int r,int x){
        if(l == r)return mx[p];
        int mid = l + r >> 1;
        if(x <= mid)return ask(query(p<<1,l,mid,x),mx[p],x);
        else return ask(query(p<<1|1,mid+1,r,x),mx[p],x);
    }
}t; 



int main(){
    scanf("%d",&n);
    for(int i = 1;i <= n;i++){
        int op,a,b,c,d;
        scanf("%d%d",&op,&a);a = (a+las-1)%m1+1;
        if(op == 0)printf("%d\n",las = t.query(1,1,m1,a).id);
        else{
            scanf("%d%d%d",&b,&c,&d);
            b = (b+las-1)%m2+1,c = (c+las-1)%m1+1,d = (d+las-1)%m2+1;
            if(a > c)swap(a,c),swap(b,d);
            double k = 0,B = 0;
            if(a == c)B = max(b,d);
            else k = (double)(d - b) / (c - a),B = (double)b - a * k;
            t.modify(1,1,m1,a,c,{k,B,++m});
        }
    }

	return 0;

}

平衡树

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
const ll inf = 1e17;
int n,m,R;
struct FHQ{
    int val[N],rd[N],size[N],ls[N],rs[N],la[N],idx = 0;
    void pushup(int p){size[p] = size[ls[p]] + size[rs[p]] + 1;}
    void pushdown(int p){
        if(!la[p])return;
        la[ls[p]] ^= 1,la[rs[p]] ^= 1;
        swap(ls[p],rs[p]),la[p] = 0;
    }
    int node(int v){
        int x = ++idx;
        val[x] = v,size[x] = 1,rd[x] = rand(),ls[x] = rs[x] = la[x] = 0;
        return x;
    }
    void split(int p,int v,int &x,int &y){
        if(!p)return x = y = 0,void();
        pushdown(p);
        if(v <= size[ls[p]])y = p,split(ls[p],v,x,ls[p]);
        else x = p,split(rs[p],v-size[ls[p]]-1,rs[p],y);
        pushup(p);
    }
    int merge(int x,int y){
        if(!x || !y)return x|y;
        pushdown(x),pushdown(y);
        if(rd[x] < rd[y])return ls[y] = merge(x,ls[y]),pushup(y),y;
        else return rs[x] = merge(rs[x],y),pushup(x),x;
    }
    void insert(int v){
        int x = 0,y = 0;
        split(R,v-1,x,y),R = merge(merge(x,node(v)),y);
    }
    void reserve(int l,int r){
        int x = 0,y = 0,z = 0;
        split(R,r,x,z),split(x,l-1,x,y);
        la[y] ^= 1;
        R = merge(merge(x,y),z);
    }
    void prin(int x){
        if(!x)return;
        pushdown(x);
        prin(ls[x]);
        printf("%d ",val[x]);
        prin(rs[x]);
    }
}t;
int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++)t.insert(i);
    for(int i = 1;i <= m;i++){
        int x,y;scanf("%d%d",&x,&y);
        t.reserve(x,y);
    }
    t.prin(R);
    printf("\n");

	return 0;

}

数位 DP

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
const ll inf = 1e17;
ll l,r;
ll f[15],ksm[15],c[15],now[15];
ll dfs(int p,int x,bool f0,bool lim){
    if(!p)return 0;
    if(!f0 && !lim && f[p] != -1)return f[p];
    ll cnt = 0;
    int lst = lim ? c[p] : 9;
    for(int i = 0;i <= lst;i++){
        if(f0 && i == 0)cnt += dfs(p-1,x,1,lim && (i==lst));
        else if(i == x && lim && i == lst)cnt += now[p-1] + 1 + dfs(p-1,x,0,lim && (i==lst));
        else if(i == x)cnt += ksm[p-1] + dfs(p-1,x,0,lim && (i==lst));
        else cnt += dfs(p-1,x,0,lim && (i==lst));
    }
    if(!lim && !f0)f[p] = cnt;
    return cnt;
}
ll sum(ll d,ll x){
    int l = 0;
    memset(f,-1,sizeof f);
    memset(now,0,sizeof now);
    while(d){
        c[++l] = d % 10;
        d /= 10;
        now[l] = now[l-1] + ksm[l-1] * c[l];
    }
    return dfs(l,x,1,1);
}
int main(){
    ksm[0] = 1;
    for(int i = 1;i <= 12;i++)ksm[i] = ksm[i - 1] * 10ll;
    scanf("%lld%lld",&l,&r);
    if(l > r)swap(l,r);
    for(int i = 0;i <= 9;i++)printf("%lld ",sum(r,i) - sum(l-1,i));
    printf("\n");

	return 0;

}
posted @ 2024-11-29 20:59  oXUo  阅读(7)  评论(0编辑  收藏  举报
网站统计