洛谷 贪婪大陆--线段树
问的就是 每次给你区间 l--r,每次覆盖一种不同的颜色,查询l--r有多少种不同的颜色
这个问题本质是在问区间l--r有多少不同的区间,利用前缀和计算一下,具体看代码
#include<iostream> #include<queue> #include<cstring> using namespace std; const int maxn = 2e5+111; typedef long long ll; struct Node{ ll val,l,r; ll lazy; }tree[3][maxn*4]; int push(int id,int node,int be,int en){ int mid = be + en >> 1; int l = node*2; int r = node*2+1; if(tree[id][node].lazy){ tree[id][l].val += (mid - be + 1)*tree[id][node].lazy; tree[id][r].val += (en - mid)*tree[id][node].lazy; tree[id][l].lazy += tree[id][node].lazy; tree[id][r].lazy += tree[id][node].lazy; tree[id][node].lazy = 0; } return 0; } int update(int id,int node,int be,int en,int LL,int RR,int val){ int mid = be + en >> 1; int l = node*2; int r = node*2+1; if(LL <= be && en <= RR){ tree[id][node].val += (en - be + 1)*val; tree[id][node].lazy += val; return 0; } push(id,node,be,en); if(LL <= mid) update(id,l,be,mid,LL,RR,val); if(RR > mid) update(id,r,mid+1,en,LL,RR,val); tree[id][node].val = tree[id][l].val + tree[id][r].val; return 0; } int ask(int id,int node,int be,int en,int LL,int RR){ if(LL == 0 || RR == 0) return 0; int mid = be + en >> 1; int l = node*2; int r = node*2+1; if(LL <= be && en <= RR){ return tree[id][node].val; } push(id,node,be,en); ll a=0,b=0; if(LL <= mid) a = ask(id,l,be,mid,LL,RR); if(RR > mid) b = ask(id,r,mid+1,en,LL,RR); return a+b; } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ int op; scanf("%d",&op); if(op == 1){//覆盖 int x,y; scanf("%d%d",&x,&y); update(0,1,1,n,y+1,n,1);//前缀 update(1,1,1,n,x,y,1); } else{ int x,y; scanf("%d%d",&x,&y); ll a = ask(0,1,1,n,y,y) - ask(0,1,1,n,x,x); a += ask(1,1,1,n,y,y); printf("%lld\n",a); } } return 0; }
寻找真正的热爱