回顾noi 2017
DAY1
整数
压位维护序列。用线段树维护一段0后第一个1,一段A-1后第一个<(A - 1)的数
推推转移式子即可
代码犯了无数个错误,并且检查的时候没有仔细的检查出来,仍然借助gdb和对拍才调出来!非常糟糕!
**1. 线段树初始化错误
**2. 打错变量名3处
3. 进位后写成减M,应该是M+1
4. 很多地方一开始想清楚,改的时候没有想清楚,反而改错。比如二分是找最低位非满或非0.修改的时候一定要想清楚,很多时候找到错误反而没有全面的修改,浪费了更多时间
写代码前细节在头脑中不清晰,代码写得太少了!
#include<bits/stdc++.h>
using namespace std;
#define maxn 1002020
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define rvc(i,S) for(register int i = 0 ; i < (int)S.size() ; i++)
#define rvcd(i,S) for(register int i = ((int)S.size()) - 1 ; i >= 0 ; i--)
#define fore(i,x)for (register int i = head[x] ; i ; i = e[i].next)
#define pb push_back
#define prev prev_
#define stack stack_
#define mp make_pair
#define fi first
#define se second
#define inf 0x3f3f3f3f
typedef long long ll;
typedef pair<int,int> pr;
const ll M = (1 << 30) - 1,K = 30;
int cov[maxn << 2],tag[maxn << 2],val[maxn << 2];
// 1 : 全为M
// 2 :全为 0
// 0 :无性质
int n,t1,t2,t3,L;
void build(int x,int l,int r){
tag[x] = 2 , cov[x] = -1;
if ( l == r ) return;
int mid = (l + r) >> 1;
build(x << 1,l,mid) , build((x << 1) | 1,mid + 1,r);
}
inline void cover(int x,int d){
cov[x] = d , val[x] = d;
if ( d == M ) tag[x] = 1;
else tag[x] = 2;
}
inline void pushdown(int x){
int ls = x << 1,rs = (x << 1) | 1;
if ( cov[x] != -1 ){
cover(ls,cov[x]);
cover(rs,cov[x]);
cov[x] = -1;
}
}
inline void update(int x){
int ls = x << 1,rs = (x << 1) | 1;
if ( tag[ls] == 1 && tag[rs] == 1 ) tag[x] = 1;
else if ( tag[ls] == 2 && tag[rs] == 2 ) tag[x] = 2;
else tag[x] = 0;
}
void modify(int x,int l,int r,int L,int R,int d){
if ( L > R ) return;
if ( L <= l && R >= r ){
cover(x,d);
return;
}
int ls = x << 1,rs = (x << 1) | 1,mid = (l + r) >> 1;
pushdown(x);
if ( L <= mid ) modify(ls,l,mid,L,R,d);
if ( R > mid ) modify(rs,mid + 1,r,L,R,d);
update(x);
}
void modify(int x,int l,int r,int id,int d){
if ( l == r ){
val[x] += d;
if ( val[x] == M ) tag[x] = 1;
else if ( val[x] == 0 ) tag[x] = 2;
else tag[x] = 0;
return;
}
int ls = x << 1,rs = (x << 1) | 1,mid = (l + r) >> 1;
pushdown(x);
if ( id <= mid ) modify(ls,l,mid,id,d);
else modify(rs,mid + 1,r,id,d);
update(x);
}
int find1(int x,int l,int r,int L,int R){
if ( tag[x] == 2 ) return 0;
if ( l == r ) return l;
int ls = x << 1,rs = (x << 1) | 1,mid = (l + r) >> 1;
pushdown(x);
if ( L <= l && R >= r ){
if ( tag[ls] == 2 ) return find1(rs,mid + 1,r,L,R);
return find1(ls,l,mid,L,R);
}
int p = 0;
if ( L <= mid ) p = find1(ls,l,mid,L,R);
if ( p ) return p;
return find1(rs,mid + 1,r,L,R);
}
int find0(int x,int l,int r,int L,int R){
if ( tag[x] == 1 ) return 0;
if ( l == r ) return l;
int ls = x << 1,rs = (x << 1) | 1,mid = (l + r) >> 1;
pushdown(x);
if ( L <= l && R >= r ){
if ( tag[ls] == 1 ) return find0(rs,mid + 1,r,L,R);
return find0(ls,l,mid,L,R);
}
i