题面
洛谷版,数据更水
做法:
- 我会线段树!
写这玩意不是在自虐吗?
此处贴上我们wjy同学的做法:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int n,m;
struct segment_tree
{
#define mid ((l+r)>>1)
#define ls (k<<1)
#define rs (k<<1|1)
struct node{int v,laz;}f[N<<2];
void pushup(int k){f[k] = {f[ls].v+f[rs].v,f[k].laz};}
void pushdown(int k,int l,int r)
{
if(!f[k].laz||l==r)return f[k].laz = 0,void();
f[ls].laz = f[k].laz,f[rs].laz = f[k].laz;
f[ls].v = 0,f[rs].v = 0;
f[k].laz = 0;
}
void init(int k,int l,int r)
{
if(l==r)return f[k] = {1,0},void();
init(ls,l,mid),init(rs,mid+1,r);
pushup(k);
}
void modify(int k,int l,int r,int x,int y)
{
if(x<=l&&r<=y)return f[k] = {0,1},void();
pushdown(k,l,r);
if(x<=mid)modify(ls,l,mid,x,y);
if(mid<y)modify(rs,mid+1,r,x,y);
pushup(k);
}
int query(){return f[1].v;}
}st;
int main()
{
scanf("%d%d",&n,&m);
st.init(1,1,n);
for(int i = 1,l,r;i<=m;i++)
{
scanf("%d%d",&l,&r);
st.modify(1,1,n,l,r);
printf("%d\n",st.query());
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000001;
int fa[MAXN];
int find(int x) {
if (fa[x] == 0)
return x;
return fa[x] = find(fa[x]);
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
int s = n;
while (m--) {
int l, r;
scanf("%d%d", &l, &r);
for (int i = find(l); i <= r; i = find(i)) {
fa[i] = i + 1;
s--;
}
printf("%d\n", s);
}
return 0;
}
- 我会ODT!
我的做法,较线段树简单,较并查集直接。
#include<bits/stdc++.h>
using namespace std;
using ODT=map<int,bool>;
int tot,l,r,n,m;
ODT odt;
void split(int l){
odt[l]=prev(odt.upper_bound(l))->second;
}
void assign(int l,int r,bool v){
split(l);split(r+1);
auto it=odt.find(l),end=odt.find(r+1);
while(it!=end){
int x=it->first;
bool y=it->second;
it=odt.erase(it);
if(y&&!v)tot-=it->first-x;
}
odt[l]=v;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
tot=n;
odt[1]=1;
odt[n+1]=0;
while(m--){
cin >> l >> r;
assign(l,r,0);
cout << tot << '\n';
}
return 0;
}