「NOI2022 D2T2 冒泡排序」题解
题意
构造长为
题解
21pts 暴力
先进行一些观察:
- 逆序对只关心相对大小,所以
必然 ,可以完全离散化 - 经典结论:若
且交换后合法,则交换后更优
A
类似一个普及贪心题:按
此时所有限制都满足了,剩下的位置可以随意填
B
相当于一些位置给定,其余位置随意
根据观察 2,空位是有序的,内部没有逆序对
一个自然的想法是单独考虑每个空位,令其与给定位置的逆序对数最少。事实上这样就能满足空位有序(反证,若有空位
也可以用决策单调性证明:
从前到后依次考虑每个空位,设
空位会填
给定位置会令
C
相当于限制是独立的
根据观察 2,每个限制一定是在
根据 B 猜测
证明类似。首先不论填什么都会使
正解
与 C 相比限制有重叠
时间复杂度
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std; using namespace __gnu_pbds; using namespace __gnu_cxx;
#define For(i,x,y,...) for(int i=x,##__VA_ARGS__;i<=(y);++i)
#define rFor(i,x,y,...) for(int i=x,##__VA_ARGS__;i>=(y);--i)
#define Rep(i,x,y,...) for(int i=x,##__VA_ARGS__;i<(y);++i)
#define pb emplace_back
#define sz(a) int((a).size())
#define all(a) (a).begin(),(a).end()
#define fi first
#define se second
#define mkp make_pair
typedef long long LL; typedef vector<int> Vi; typedef pair<int,int> Pii;
auto ckmax=[](auto &x,auto y) { return x<y ? x=y,true : false; };
auto ckmin=[](auto &x,auto y) { return y<x ? x=y,true : false; };
sfmt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l,int r) { return uniform_int_distribution<>(l,r)(mt); }
#define getchar() getchar_unlocked()
struct IO {
template<typename T>IO& operator >> (T &x) {
x=0;bool f=0;char c;while(!isdigit(c=getchar()))f|=c=='-';
do x=x*10+c-48;while(isdigit(c=getchar()));if(f)x=-x;
return *this;
}
} io;
#define cin io
template<typename T=int>T read() { T x; cin>>x; return x; }
const int mod = 998244353;
struct mint {
int x; mint(int x=0):x(x<0?x+mod:x<mod?x:x-mod){}
mint(LL y) { y%=mod, x=y<0?y+mod:y; }
mint& operator += (const mint &y) { x=x+y.x<mod?x+y.x:x+y.x-mod; return *this; }
mint& operator -= (const mint &y) { x=x<y.x?x-y.x+mod:x-y.x; return *this; }
mint& operator *= (const mint &y) { x=1ll*x*y.x%mod; return *this; }
friend mint operator + (mint x,const mint &y) { return x+=y; }
friend mint operator - (mint x,const mint &y) { return x-=y; }
friend mint operator * (mint x,const mint &y) { return x*=y; }
}; mint Pow(mint x,LL y=mod-2) { mint z(1);for(;y;y>>=1,x*=x)if(y&1)z*=x;return z; }
const int N = 1e6+5;
int n,m,o[N],L[N],R[N],V[N],a[N],b[N];
vector<Pii> q[N];
int fa[N];
int find(int x) { return fa[x]==x ? x : fa[x]=find(fa[x]); }
#define ls (u<<1)
#define rs (u<<1|1)
#define mid (l+r>>1)
struct { int add; Pii mn; } t[N*4];
Pii operator + (const Pii &x,const Pii &y) { return x.fi<=y.fi ? x : y; }
void bld(int u=1,int l=1,int r=o[0]) {
t[u] = {0,{0,l}};
if( l == r ) return;
bld(ls,l,mid), bld(rs,mid+1,r);
}
void add(int ql,int qr,int x,int u=1,int l=1,int r=o[0]) {
if( qr < l || r < ql ) return;
if( ql <= l && r <= qr ) { t[u].add += x, t[u].mn.fi += x; return; }
add(ql,qr,x,ls,l,mid), add(ql,qr,x,rs,mid+1,r);
t[u].mn = t[ls].mn + t[rs].mn, t[u].mn.fi += t[u].add;
}
Pii argmin(int ql,int u=1,int l=1,int r=o[0]) {
if( r < ql ) return {1e9,0};
if( ql <= l ) return t[u].mn;
Pii res = argmin(ql,ls,l,mid) + argmin(ql,rs,mid+1,r);
return res.fi += t[u].add, res;
}
struct {
int t[N];
void clr() { memset(t+1,0,sizeof(int)*o[0]); }
void add(int i) { for(;i;i-=i&-i)++t[i]; }
int sum(int i) { int res=0; for(;i<=o[0];i+=i&-i)res+=t[i]; return res; }
} ft;
void MAIN() {
cin>>n>>m; For(i,1,m) cin>>L[i]>>R[i]>>V[i], o[++o[0]] = V[i];
sort(o+1,o+o[0]+1), o[0] = unique(o+1,o+o[0]+1)-o-1;
For(i,1,m) q[lower_bound(o+1,o+o[0]+1,V[i])-o].pb(L[i],R[i]);
iota(fa+1,fa+n+2,1);
rFor(i,o[0],1) {
sort(all(q[i]),greater<>());
int lst = n+1;
for(auto [l,r] : q[i]) if( r < lst ) {
int p = find(l);
if( p > r ) { cout<<"-1\n"; return; }
a[p] = i, lst = p;
}
for(auto [l,r] : q[i])
for(int p = find(l); p <= r; p = find(p)) b[p] = i, fa[p] = p+1;
}
// cerr<<"a: "; For(i,1,n) cerr<<a[i]<<" "; cerr<<'\n';
// cerr<<"b: "; For(i,1,n) cerr<<b[i]<<" "; cerr<<'\n';
bld();
For(i,1,n) if( a[i] ) add(a[i]+1,o[0],1);
For(i,1,n) {
if( a[i] ) add(a[i]+1,o[0],-1);
else a[i] = argmin(b[i]).se;
add(1,a[i]-1,1);
}
// cerr<<"a: "; For(i,1,n) cerr<<a[i]<<" "; cerr<<'\n';
LL ans = 0;
For(i,1,n) ans += ft.sum(a[i]+1), ft.add(a[i]);
cout<<ans<<'\n';
} signed main() {
#ifdef FT
freopen("in","r",stdin); freopen("out","w",stdout);
#endif
ios::sync_with_stdio(0);
int lft=read(); while( lft-- ) {
MAIN();
ft.clr();
For(i,1,o[0]) q[i].clear();
memset(a+1,0,sizeof(int)*n), memset(b+1,0,sizeof(int)*n);
o[0] = 0;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具