The Preliminary Contest for ICPC Asia Shanghai 2019 B题
线段树的样子,但基本在于区间修改,取异或,然后只查询一次
刚出炉的Shanghai网络赛
传送门
超内存版线段树
#include
#include
#include
#include
#define lch(x) x<<1
#define rch(x) x<<1|1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN=1e6+5;
int cover[MAXN<<2];
int sum[MAXN<<2];
inline int read(){//快读
char ch=getchar();int x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void up(int rt){//更新本节点
sum[rt] = sum[lch(rt)] + sum[rch(rt)];
}
void down(int rt, int l, int r){
if(cover[rt]){
cover[lch(rt)] ^= 1;
cover[rch(rt)] ^= 1;
int m = (l + r) >> 1;
sum[lch(rt)] = m - l + 1 - sum[lch(rt)];
sum[rch(rt)] = r - m - sum[rch(rt)];
cover[rt] = 0;
}
}
void update(int L, int R, int l, int r, int rt){//更新
if(L <= l && R >= r){
cover[rt] ^= 1;
sum[rt] = r - l + 1 - sum[rt];
return;
}
down(rt, l, r);
int m = (l + r) >> 1;
if(L <= m) update(L, R, lson);
if(R > m) update(L, R, rson);
up(rt);
}
int query(int L, int R, int l, int r, int rt){
if(L <= l && R >= r) return sum[rt];
down(rt, l, r);
int m = (l + r) >> 1;
int ret = 0;
if(L <= m) ret += query(L, R, lson);
if(R > m) ret += query(L, R, rson);
return ret;
}
int main(){
int x;
x=read();
int n,m;
for(int k=1;k<=x;k++){
memset(cover,0,sizeof(cover));
memset(sum,0,sizeof(sum));
n=read(),m=read();
for(int i=0;i
超时间版差分
既然超内存,想到线段树其实就是修改和查询
因为只查询一次,那么超内存的的话,用差分来减少内存
#include
#include
#include
#define rep(i,a,b) for(int i=a;i
差分优化版
差分也需要遍历全部,导致时间复杂度高,所以重点在于减少差分的时间,用map优化,也就是离散化
/*
不能用线段树,爆内存,不能遍历n,o(t*n),爆时间
差分思想+map容器
*/
#include
#include
#include