HDU - 6183:Color it (线段树&动态开点||CDQ分治)
Do you like painting? Little D doesn't like painting, especially messy color paintings. Now Little B is painting. To prevent him from drawing messy painting, Little D asks you to write a program to maintain following operations. The specific format of these operations is as follows.
0 0 : clear all the points.
1 1 x x y y c c : add a point which color is c c at point (x,y) (x,y) .
2 2 x x y 1 y1 y 2 y2 : count how many different colors in the square (1,y1) (1,y1) and (x,y2) (x,y2) . That is to say, if there is a point (a,b) (a,b) colored c c , that 1≤a≤x 1≤a≤x and y 1 ≤b≤y 2 y1≤b≤y2 , then the color c c should be counted.
3 3 : exit.
0 0 : clear all the points.
1 1 x x y y c c : add a point which color is c c at point (x,y) (x,y) .
2 2 x x y 1 y1 y 2 y2 : count how many different colors in the square (1,y1) (1,y1) and (x,y2) (x,y2) . That is to say, if there is a point (a,b) (a,b) colored c c , that 1≤a≤x 1≤a≤x and y 1 ≤b≤y 2 y1≤b≤y2 , then the color c c should be counted.
3 3 : exit.
InputThe input contains many lines.
Each line contains a operation. It may be '0', '1 x y c' ( 1≤x,y≤10 6 ,0≤c≤50 1≤x,y≤106,0≤c≤50
), '2 x y1 y2' (1≤x,y 1 ,y 2 ≤10 6 1≤x,y1,y2≤106
) or '3'.
x,y,c,y1,y2 x,y,c,y1,y2
are all integers.
Assume the last operation is 3 and it appears only once.
There are at most 150000 150000
continuous operations of operation 1 and operation 2.
There are at most 10 10
operation 0.
OutputFor each operation 2, output an integer means the answer .
Sample Input
0 1 1000000 1000000 50 1 1000000 999999 0 1 1000000 999999 0 1 1000000 1000000 49 2 1000000 1000000 1000000 2 1000000 1 1000000 0 1 1 1 1 2 1 1 2 1 1 2 2 2 1 1 2 1 2 2 2 2 1 1 2 1 2 1 3 2 2 1 2 2 10 1 2 2 10 2 2 0 1 1 1 1 2 1 1 1 1 1 2 1 2 1 1 2 1 2 2 1 2 1 1 2 1 2 1 1 2 2 1 2 2 10 1 2 2 10 2 2 3
Sample Output
2 3 1 2 2 3 3 1 1 1 1 1 1 1
题意:给定一个1e6*1e6的矩阵,有四种操作,0是清空矩阵;1是给某点加一个颜色c;2是查询某个区间(1,y1)到(x2,y2)的颜色数,3是退出。
思路:由于矩阵位置的特殊性,都是x=1开始,那么我们就是查询每种颜色在区间(y1,y2)是否有点的最小值小于x2。 用线段树维护区间最小值,动态开点。
(日后来补CDQ分治。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=2000010; struct in{ int l,r,v; in(){l=r=v=0;} }s[maxn<<1]; int rt[51],cnt; void update(int &Now,int L,int R,int pos,int val) { if(!Now) Now=++cnt,s[Now].v=val; s[Now].v=min(s[Now].v,val); if(L==R) return ; int Mid=(L+R)>>1; if(pos<=Mid) update(s[Now].l,L,Mid,pos,val); else update(s[Now].r,Mid+1,R,pos,val); } bool query(int Now,int L,int R,int l,int r,int pos) { if(!Now) return false; if(l<=L&&r>=R) return s[Now].v<=pos; int Mid=(L+R)>>1; if(l<=Mid) if(query(s[Now].l,L,Mid,l,r,pos)) return true; if(r>Mid) if(query(s[Now].r,Mid+1,R,l,r,pos)) return true; return false; } int main() { int opt,x1,y1,x2,y2,c; while(scanf("%d",&opt)){ if(opt==0){ rep(i,0,50) rt[i]=0; rep(i,1,cnt) s[i].l=s[i].r=s[i].v=0;cnt=0; } else if(opt==1){ scanf("%d%d%d",&x1,&y1,&c); update(rt[c],1,1000000,y1,x1); } else if(opt==2){ scanf("%d%d%d",&x2,&y1,&y2); int ans=0; rep(i,0,50) ans+=query(rt[i],1,1000000,y1,y2,x2); printf("%d\n",ans); } else break; } return 0; }
It is your time to fight!