多校A层冲刺NOIP2024模拟赛07

rank 7,T1 100pts,T2 0pts,T3 70pts,T4 16pts

accoder上rank31,同分

限速(speed)

签,糖。

打的\(O(m\log V)\)的。

考虑分类讨论,有两种情况。

  1. 最大值是由最小的转化过来的,那么就是看边权\(\le k\)的是否可以构成一颗最大生成树,时间复杂度\(O(m\log m)\)

  2. 最大值是由更大的减下来的,发现如果小的可以,那么大的也可以,答案具有单调性,考虑二分答案。假设当前二分到的答案为\(mid\),那么\(check(mid)\)表示可否使用边权\(\le mid\)的构成一个生成树。但这个生成树必须强制将边权\(\le mid\)的最大的边加入进去,剩下的跑最小生成树,然后记录该生成树需要的边,如果有边权\(>k\),那么答案\(+=边权-k\)

最后答案取min,时间复杂度\(O(m\log m + m\log V)\)

然而事实是只需要求最小生成树和边权\(\le k\)构成的最大生成树即可

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(#x".in","r",stdin)
#define outfile(x) freopen(#x".out","w",stdout)
#define errfile(x) freopen(#x".err","w",stderr)
#define ansfile(x) freopen(#x".ans","w",stdout)
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#ifdef LOCAL
    FILE *InFile = infile(in),*OutFile = outfile(out);
    // FILE *ErrFile = errfile(err);
#else
    FILE *Infile = infile(speed),*OutFile = outfile(speed);
    //FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#define int long long
const int N = 2e5 + 10,M = 2e5 + 10,inf = 0x3f3f3f3f3f3f3f3f;
int fa[N],n,m,k,ans = inf;
struct node{
    int u,v,w;
    bool operator < (node x) const{return w < x.w;}
}e[M];
int get_fa(int x){return x==fa[x]?x:fa[x] = get_fa(fa[x]);}
bitset<N> vis;
inline bool check1(int mid){
    rep(i,1,n,1) fa[i] = i;
    rep(i,1,m,1) vis[i] = false;
    int pos = upper_bound(e+1,e+1+m,node{0,0,mid}) - e - 1;
    drep(i,pos,1,1){
        int fx = get_fa(e[i].u),fy = get_fa(e[i].v);
        if(fx == fy) continue;
        fa[fx] = fy;
        vis[i] = true;
    }
    rep(i,2,n,1) if(get_fa(i) != get_fa(i-1)) return false;
    return true;
}
inline void get_ans1(int l,int r){
    bool flag = check1(k);
    int pos = upper_bound(e+1,e+1+m,node{0,0,k}) - e - 1,res = inf;
    if(!flag) return;
    drep(i,pos,1,1){if(vis[i]){res = e[i].w;break;}}
    ans = min(ans,abs(res-k));
}
inline bool check2(int mid){
    rep(i,1,n,1) fa[i] = i;
    rep(i,1,m,1) vis[i] = false;
    int pos = upper_bound(e+1,e+1+m,node{0,0,mid}) - e - 1;
    int fx = get_fa(e[pos].u),fy = get_fa(e[pos].v);
    if(fx != fy) fa[fx] = fy,vis[pos] = true;
    rep(i,1,pos-1,1){
        int fx = get_fa(e[i].u),fy = get_fa(e[i].v);
        if(fx == fy) continue;
        fa[fx] = fy;
        vis[i] = true;
    }
    rep(i,2,n,1) if(get_fa(i) != get_fa(i-1)) return false;
    return true;
}
inline void get_ans2(int l,int r){
    if(l > r) return;
    int res = -inf;
    while(l <= r){
        int mid = (l + r) >> 1;
        if(check2(mid)) res = mid,r = mid - 1;
        else l = mid + 1;
    }
    int emm = 0;
    int pos = upper_bound(e+1,e+1+m,node{0,0,res}) - e - 1;
    if(res == -inf) emm = inf;
    if(res != -inf) check2(res);
    drep(i,pos,1,1){
        if(e[i].w <= k) break;
        if(!vis[i]) continue;
        emm += abs(k-e[i].w);
    }
    ans = min(ans,emm);
}
inline void solve(){
    cin>>n>>m>>k;
    rep(i,1,m,1) cin>>e[i].u>>e[i].v>>e[i].w;
    sort(e+1,e+1+m,[](node x,node y){return x.w < y.w;});
    get_ans1(0,k);get_ans2(k+1,e[m].w);
    cout<<ans<<'\n';
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

酒鬼 (drunkard)

赛时题没看懂,部分分不会打。

大力分讨加大模拟,牛魔题。

考虑到合法状态与\(p_i+q_i\)的奇偶性有关,如果\(p_i+q_i\)的奇偶性不同,那么就是无解。而且相邻的时刻移动距离不能超过它们的时间差。

但是发现当\(p_i=1\)时不用保证奇偶性一致,因为是从1开始的。但是要保证时刻小于最晚移动时间。

然后用一个\(map/set\)记录一下每个时间对应的值,模拟就完了。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(#x".in","r",stdin)
#define outfile(x) freopen(#x".out","w",stdout)
#define errfile(x) freopen(#x".err","w",stderr)
#define ansfile(x) freopen(#x".ans","w",stdout)
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#ifdef LOCAL
    FILE *InFile = infile(in),*OutFile = outfile(out);
    // FILE *ErrFile = errfile(err);
#else
    FILE *Infile = infile(drunkard),*OutFile = outfile(drunkard);
    //FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int inf = 0x3f3f3f3f;
int n,m,nmn = 0,nmx = inf;
bool flag = true;
#define pii pair<int,int>
#define mk make_pair
map<ll,pii> mp;
inline bool check(pii p1,pii p2){
    if(abs(p2.first - p1.first) > p2.second - p1.second) return false;
    if(p1.first != 1 && p1.second <= nmn) return false;
    if(p2.first != 1) nmx = min(nmx,p2.second - p2.first + 1);
    if(p1.first == 1 && p1.second <= nmx){
        if((abs(p2.first - p1.first)&1) != ((p2.second-p1.second)&1))
            nmn = max(nmn,p1.second + 1);
        return true;
    }
    if((abs(p2.first - p1.first)&1) != ((p2.second - p1.second)&1)) return false;
    return true;
}
inline void solve(){
    cin>>n>>m;
    mp[0] = mk(1,0);
    rep(test,1,m,1){
        string op;cin>>op;
        if(op[1] == 'l'){
            int p,q;cin>>p>>q;
            if(!flag) continue;
            auto it = mp.find(q);
            if(it != mp.end()){
                if(it->second.first != p) flag = false;
                continue;
            }
            it = mp.lower_bound(q);
            if(it != mp.end() && !check(mk(p,q),it->second)){flag = false;continue;}
            it--;
            if(!check(it->second,mk(p,q))) {flag = false;continue;}
            mp[q] = mk(p,q);
        }
        if(op[1] == 'i'){
            if(!flag){cout<<"bad\n";continue;}
            cout<<nmn<<'\n';
        }
        if(op[1] == 'a'){
            if(!flag){cout<<"bad\n";continue;}
            if(nmx == inf) cout<<"inf\n";
            else cout<<nmx<<'\n';
        }
    }
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

距离(distance)

赛时打的\(O(n^2\log^2 n)\)

有一个性质\(a+b = min(a,b)+max(a,b)\),所以\(\min(∣a_x−a_y∣, ∣b_x − b_y∣)=|a_x-a_y|+|b_x-b_y|-\max(|a_x-a_y|,|b_x-b_y|)\)。然后发现后面的就是切比雪夫距离,转成曼哈顿距离,就变成了\(|p_x-p_y|+|q_x-q_y|\),其中\(p_x=\frac{a_x+b_x}{2},q_x=\frac{a_x-b_x}{2}\)

然后就变成了维护\(\sum\limits_{x\in Subtree_u}\sum\limits_{y\in Subtree_u}|a_x-a_y|+|b_x-b_y|-|p_x-p_y|-|q_x-q_y|\),分开维护,用线段树维护,拆绝对值,考虑到\(ans_x=ans_{ls}+ans_{rs}+sum_{ls}\times val_{rs}-sum_{rs}\times val_{ls}\),其中\(ls/rs\)表示\(x\)的左/右儿子,\(val_x\)表示\(x\)和,\(sum_x\)表示\(x\)数的数量,这个线段树合并即可维护。

发现\(p,q\)\(/2\)不好维护,考虑先乘二,然后乘上\(inv(2)\)即可。

最后答案要乘上二,因为反过来还有一个。

时间复杂度\(O(n\log n)\)

fhq_treap也可以维护,也是\(O(n\log n)\)的。

DSU On Tree也可以,但DSU On Tree比较慢,是\(O(n\log^2 n)\)

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(#x".in","r",stdin)
#define outfile(x) freopen(#x".out","w",stdout)
#define errfile(x) freopen(#x".err","w",stderr)
#define ansfile(x) freopen(#x".ans","w",stdout)
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#ifdef LOCAL
    FILE *InFile = infile(in),*OutFile = outfile(out);
    // FILE *ErrFile = errfile(err);
#else
    FILE *Infile = infile(distance),*OutFile = outfile(distance);
    //FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#define eb emplace_back
#define All(x) x.begin(),x.end()
namespace IO{
    char buf[1<<23],*p1,*p2;
    #define gc() (p1==p2&&(p2=(p1=buf)+fread_unlocked(buf,1,1<<23,stdin),p1==p2)?EOF:*p1++)
    #define pc putchar_unlocked
    template<class T>
    inline void read(T &x){
        x = 0;
        char s = gc();
        for(;s < '0' || s > '9';s = gc());
        for(;'0' <= s && s <= '9';s = gc()) x = (x<<1)+(x<<3)+(s^48);
    }
    template<class T,class... Args>
    inline void read(T &x,Args&... argc){read(x);read(argc...);}
    template<class T>
    inline void write(T x){
        static int sta[20],top = 0;
        do{sta[++top] = x%10,x /= 10;}while(x);
        do{pc(sta[top--]+'0');}while(top);
    }
    inline void write(char x){pc(x);}
    template<class T,class... Args>
    inline void write(T x,Args... argc){write(x);write(argc...);}
}using namespace IO;
const int N = 5e5 + 10,mod = 1e9 + 7;
int n,a[5][N],ans[N],np,rt[N];
vector<int> e[N],num[5];
struct Segment_Tree{
    struct segment_tree{
        int lc,rc,val,sum,ans;
        #define lc(x) tree[x].lc
        #define rc(x) tree[x].rc
        #define val(x) tree[x].val
        #define sum(x) tree[x].sum
        #define ans(x) tree[x].ans
    }tree[N*25];
    int tot = 0;
    inline void P(int k){
        sum(k) = sum(lc(k)) + sum(rc(k));
        val(k) = (val(lc(k)) + val(rc(k)))%mod;
    }
    void I(int &k,int l,int r,int pos,int val){
        if(!k) k = ++tot,lc(k) = rc(k) = val(k) = sum(k) = ans(k) = 0;
        if(l == r) return sum(k)++,val(k) = (val(k) + num[np][val])%mod,void();
        int mid = (l + r) >> 1;
        if(pos <= mid) I(lc(k),l,mid,pos,val);
        else I(rc(k),mid+1,r,pos,val);
        P(k);
    }
    void Merge(int &x,int y){
        if(!x) return x = y,void();
        if(!y) return;
        sum(x) += sum(y);
        val(x) = (val(x) + val(y))%mod;
        Merge(lc(x),lc(y));Merge(rc(x),rc(y));
        ans(x) = (0ll + ans(lc(x)) + ans(rc(x)) + 1ll*val(rc(x))*sum(lc(x))%mod - 1ll*val(lc(x))*sum(rc(x))%mod + mod)%mod;
    }
}T;
inline void pre(int p){
    num[p].eb(INT_MIN);
    rep(i,1,n,1) num[p].eb(a[p][i]);
    sort(All(num[p]));
    num[p].erase(unique(All(num[p])),num[p].end());
    rep(i,1,n,1) a[p][i] = lower_bound(All(num[p]),a[p][i]) - num[p].begin();
}
void dfs(int x,int f){
    T.I(rt[x],1,n,a[np][x],a[np][x]);
    for(int y:e[x]){
        if(y == f) continue;
        dfs(y,x);
        T.Merge(rt[x],rt[y]);
    }
    ans[x] = (ans[x] + T.ans(rt[x]))%mod;
}
inline void solve(){
    read(n);
    rep(i,2,n,1){int u,v;read(u,v);e[u].eb(v);e[v].eb(u);}
    rep(i,1,n,1) read(a[1][i],a[2][i]),a[3][i] = a[1][i]+a[2][i],a[4][i] = a[1][i] - a[2][i];
    rep(i,1,4,1) pre(i);
    drep(i,4,1,1){
        rep(j,1,n,1) rt[j] = 0;
        T.tot = 0,np = i;dfs(1,0);
        if(i == 3) rep(j,1,n,1) ans[j] = (-500000004ll*ans[j]%mod+mod)%mod;
    }
    rep(i,1,n,1) write(ans[i]*2%mod,'\n');
}
signed main(){solve();}

update:给神卡常卡过了,学习了一个快速取模的Barrett约减。

团队选拔(selection)

赛时打的特殊性质,但好像正解也是线段树合并。

\(n\le 10\quad O(3^n)\)搜索即可。

\(\forall i\in [1,n]\quad a_i=1\),打表可以找出规律,\(O(n)\)

好难不会。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(#x".in","r",stdin)
#define outfile(x) freopen(#x".out","w",stdout)
#define errfile(x) freopen(#x".err","w",stderr)
#define ansfile(x) freopen(#x".ans","w",stdout)
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#ifdef LOCAL
    FILE *InFile = infile(in),*OutFile = outfile(out);
    // FILE *ErrFile = errfile(err);
#else
    FILE *Infile = infile(selection),*OutFile = outfile(selection);
    //FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 1e5 + 10,mod = 998244353;
int st[18][N],n,a[N],lg[N];
inline void st_pre(){
    lg[1] = 0;
    rep(i,2,n,1) lg[i] = lg[i>>1]+1;
    int t = lg[n];
    rep(i,1,n,1) st[0][i] = a[i];
    rep(j,1,t,1) rep(i,1,n-(1<<j)+1,1){
        st[j][i] = __gcd(st[j-1][i],st[j-1][i+(1<<(j-1))]);
    }
}
inline int Q(int l,int r){
    int k = lg[r-l+1];
    return __gcd(st[k][l],st[k][r-(1<<k)+1]);
}
namespace S1{
    int b[N],ans = 0,vis[N],f[N],k[N];
    inline void get_ans(){
        int gcd = 0;
        bool flag = false;
        set<int> st;
        rep(i,1,n,1) k[i] = 0;
        rep(i,1,n,1){
            if(b[i] == 1)gcd = a[i],flag = true,k[i]++;
            if(!b[i] && vis[i]) st.insert(a[i]),k[i]++;
            if(b[i] != 1 && flag) gcd = __gcd(gcd,a[i]),k[i]++;
            if(b[i] == -1){st.insert(gcd);flag = false;}
        }
        if(st.size() < 2) rep(i,1,n,1) f[i] += k[i];
    }
    void dfs(int now,bool flag){
        if(now == n+1){
            if(!flag) return;
            else get_ans();
            return;
        }
        b[now] = 0;vis[now] = false;
        dfs(now+1,flag);
        b[now] = flag?1:-1;
        dfs(now+1,flag^1);
        if(flag) b[now] = 0,vis[now] = true,dfs(now+1,true);
    }
    inline void solve(){
        dfs(1,true);
        rep(i,1,n,1) cout<<f[i]<<' ';
    }
}
namespace S2{
    int f[N],g[N],ans[N];
    inline int power(int a,int b,int mod){
        int res = 1;
        for(;b;b >>= 1,a = 1ll*a*a%mod) if(b&1) res = 1ll*res*a%mod;
        return res;
    }
    inline void solve(){
        f[1] = g[1] = 1;
        f[2] = 1,g[2] = 3;
        rep(i,3,n,1) 
            f[i] = (f[i-1]+f[i-2])%mod,
            g[i] = (g[i-1]+g[i-2])%mod;
        ans[1] = 1ll*f[n]*g[n]%mod;
        rep(i,2,ceil(n/2.0),1)
            ans[i] = (ans[i-1]+1ll*f[n-(2*(i-1))]*g[n-(2*(i-1))]%mod)%mod;
        rep(i,n/2+1,n,1) ans[i] = ans[n-i+1];
        rep(i,1,n,1) cout<<ans[i]<<' ';
    }  
} 
inline void solve(){
    cin>>n; rep(i,1,n,1) cin>>a[i];
    // st_pre();
    int tot = 0;
    rep(i,1,n,1) if(a[i] == 1) tot++;
    if(tot == n) return S2::solve(),void();
    return S1::solve(),void();
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

挂个官解和std

image

image

image

点此查看代码
#include<bits/stdc++.h>
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
	char c=getchar();int x=0;while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int mod=998244353,maxn=100005;
struct sode{int l,r,v;}st[maxn],bl[maxn];
struct node{int l,r,x,v;}A[maxn*30],B[maxn*30];
struct Seg{int l,r,v;}seg[2][maxn];
int gcd(int a,int b) {return !b?a:gcd(b,a%b);}
inline int dqm(int x) {return x<0?x+mod:x;}
inline int qm(int x) {return x>=mod?x-mod:x;} 
inline int cmp(const node &A,const node &B){
	return A.v==B.v?A.x<B.x:A.v<B.v;
}
inline int ctp(const node &A,const node &B) {
	return A.v==B.v?A.x>B.x:A.v<B.v;
}
int n,a[maxn],top,sa,sb,lp,sz[2],ans,pre[maxn];
int l[maxn*3],r[maxn*3],tag[maxn*3],d[maxn*3];
inline void pushup(int i) {d[i]=qm(d[i<<1]+d[i<<1|1]);}
inline void pushr(int i,int v) {
	tag[i]=v;d[i]=1ll*(r[i]-l[i]+1)*v%mod;
}
inline void pushdown(int i) {
	if(tag[i]==-1) return;pushr(i<<1,tag[i]);
	pushr(i<<1|1,tag[i]);tag[i]=-1;
}
void bud(int x,int y,int i) {
	l[i]=x,r[i]=y,tag[i]=-1;if(x==y) return;
	int mid=x+y>>1;bud(x,mid,i<<1),bud(mid+1,y,i<<1|1);
}
void chg(int x,int y,int v,int i) {
	if(x<=l[i]&&y>=r[i]) {pushr(i,v);return;}
	int mid=l[i]+r[i]>>1;pushdown(i);
	if(x<=mid) chg(x,y,v,i<<1);
	if(y>mid) chg(x,y,v,i<<1|1);pushup(i);
}
int qry(int x,int y,int i) {
	if(x<=l[i]&&y>=r[i]) return d[i];
	int mid=l[i]+r[i]>>1;pushdown(i);
	return qm((x<=mid?qry(x,y,i<<1):0)+(y>mid?qry(x,y,i<<1|1):0));
}
inline void ins(int l,int r,int v,int o) {
	if(r>n)r=n;if(l<1)l=1;if(l>r) return;
	seg[o][++sz[o]]=(Seg){l,r,v};
}
inline void calc(int l,int r,int v) {
	pre[l]=qm(pre[l]+v),pre[r+1]=dqm(pre[r+1]-v);
} 
inline void solve(int L,int R) {
	int lst=0,v=0;sz[0]=sz[1]=0;
	for(int i=L;i<=R;++i) {
		chg(lst,A[i].x-1,v,1);
		ins(lst+1,A[i].x,qm(v+1),0);
		lst=A[i].x;
		v=qm(v+qry(A[i].l-1,A[i].r-1,1));
		v=qm(v+A[i].r-A[i].l+1);
	}  
	chg(lst,n,v,1);
	ins(lst+1,n+1,qm(v+1),0);
	lst=n+1,v=0;int rp=lp;
	while(lp<=sb&&B[lp].v==A[L].v) ++lp;
	for(int i=rp;i<lp;++i) {
		chg(B[i].x+1,lst,v,1);
		ins(B[i].x,lst-1,qm(v+1),1);
		lst=B[i].x;
		v=qm(v+qry(B[i].l+1,B[i].r+1,1));
		v=qm(v+B[i].r-B[i].l+1);
	}  
	chg(1,lst,v,1);ans=qm(ans+v);
	ins(0,lst-1,qm(v+1),1);
	std::reverse(seg[1],seg[1]+sz[1]+1);
	int x,y;x=0,y=0;
	while(x<=sz[0]&&y<=sz[1]) {
		calc(max(seg[0][x].l,seg[1][y].l),min(seg[0][x].r,seg[1][y].r),dqm(1ll*seg[0][x].v*seg[1][y].v%mod-1));
		if(seg[0][x].r<seg[1][y].r) ++x;
		else if(seg[0][x].r>seg[1][y].r) ++y;
		else if(seg[0][x].r==seg[1][y].r) ++y,++x;
	}
}
int main() {
	freopen("selection.in", "r", stdin);
	freopen("selection.out", "w", stdout);
	n=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=top;++j) 
			st[j].v=gcd(st[j].v,a[i]);
		st[++top]=(sode){i,i,a[i]};
		int tot=0,x=i,y=i;
		for(int j=top-1;j>=0;--j) {
			if(st[j].v!=st[j+1].v) {
				bl[++tot].l=x,bl[tot].r=y;
				bl[tot].v=st[j+1].v;
				x=st[j].l,y=st[j].r;
			}else x=st[j].l;
		}
		top=0;
		while(tot) st[++top]=bl[tot--];
		for(int j=1;j<=top;++j) 
			A[++sa]=(node){st[j].l,st[j].r,i,st[j].v};
	}
	top=0;
	for(int i=n;i;i--) {
		for(int j=1;j<=top;++j) 
			st[j].v=gcd(st[j].v,a[i]);
		st[++top]=(sode){i,i,a[i]};
		int tot=0,x=i,y=i;
		for(int j=top-1;j>=0;--j) 
			if(st[j].v!=st[j+1].v) {
				bl[++tot].l=x,bl[tot].r=y;
				bl[tot].v=st[j+1].v;
				x=st[j].l,y=st[j].r;
			} else y=st[j].r;
		top=0;
		while(tot) st[++top]=bl[tot--];
		for(int j=1;j<=top;++j) 
			B[++sb]=(node){st[j].l,st[j].r,i,st[j].v};
	}
	std::sort(A+1,A+sa+1,cmp);std::sort(B+1,B+sb+1,ctp);
	int L=1;lp=1;
	bud(0,n+1,1);
	for(int i=2;i<=sa+1;++i) 
		if(A[i].v!=A[i-1].v) 
			solve(L,i-1),L=i;
	for(int i=1;i<=n;i++)pre[i]=qm(pre[i-1]+pre[i]);
	for(int i=1;i<=n;i++)printf("%d ",dqm(ans-pre[i]));
	return 0;
}
posted @ 2024-10-15 20:23  CuFeO4  阅读(29)  评论(2编辑  收藏  举报