後綴數組ios
poj 1743數組
poj 3415ide
poj 2758測試
線段樹ui
poj 2828spa
每一個人依次插隊, pos表示這我的會差到第pos我的的右邊, 樹狀數組維護,開始的時候全置1,表示每一個位置都有一我的,就是最終的狀態,而後按照時間順序 倒序處理. 先處理最後一我的, 二分出前n項和等於其pos+1的位置, 那麼這我的就會在這個位置, 對於最後一我的, 他剛好在 pos位置, 而後最後一我的的位置肯定了, 樹狀數組改位置清零, 狀態就是除去這我的的狀態, 而後處理倒數第二我的, 以此類推. 線段樹有個比較巧妙的寫法,3年前的工做了, 也貼一下吧. 雖然測試沒快多少, 可是樹狀數組n*logn*logn,由於有二分, 線段樹只有nlogn. 線段樹結點存區間的和, 查詢一個值時, 左兒子和若是足夠,就走左邊, 不然減去左邊的和,剩餘部分走右邊,返回走到葉子結點的id.debug
array3d
1 //#define txtout 2 //#define debug 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<stack> 13 #include<queue> 14 #include<set> 15 #include<map> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double pi=acos(-1.0); 20 const double eps=1e-8; 21 const int inf=0x3f3f3f3f; 22 const int M=2e5+10; 23 class One_Tree_Array { ///一維樹狀數組 24 static const int M=2e5+10; ///點的個數 25 typedef int typev; 26 typev a[M]; 27 int n; 28 public: 29 void init(int tn) { ///傳入點數,點下標 1 開始 30 n=tn; 31 for(int i=0; i<=n; i++) a[i]=0; 32 } 33 int lowb(int t) { 34 return t&(-t); 35 } 36 void add(int i,typev v) { 37 for(; i<=n; a[i]+=v,i+=lowb(i)); 38 } 39 typev sum(int i) { 40 typev s=0; 41 for(; i>0; s+=a[i],i-=lowb(i)); 42 return s; 43 } 44 } tree; 45 int n; 46 struct Q { 47 int pos,val; 48 } p[M]; 49 int answer[M]; 50 int Binary(int x){ 51 int L=0,R=n-1,result=0; 52 while(L<=R){ 53 int mid=(L+R)>>1; 54 if(tree.sum(mid+1)>=x){ 55 result=mid; 56 R=mid-1; 57 } 58 else{ 59 L=mid+1; 60 } 61 } 62 return result; 63 } 64 void solve() { 65 tree.init(n); 66 for(int i=1;i<=n;i++){ 67 tree.add(i,1); 68 } 69 for(int i=n-1;i>=0;i--){ 70 int to=Binary(p[i].pos+1); 71 answer[to]=p[i].val; 72 tree.add(to+1,-1); 73 } 74 } 75 int main() { 76 #ifdef txtout 77 freopen("in.txt","r",stdin); 78 freopen("out.txt","w",stdout); 79 #endif // txtout 80 while(~scanf("%d",&n)) { 81 for(int i=0; i<n; i++) { 82 scanf("%d%d",&p[i].pos,&p[i].val); 83 } 84 solve(); 85 for(int i=0; i<n; i++) { 86 if(i) putchar(' '); 87 printf("%d",answer[i]); 88 } 89 puts(""); 90 } 91 return 0; 92 }
segment treecode
1 #include<cstdio> 2 const int M=200010; 3 int tree[M<<2]; 4 int ans[M]; 5 int pos[M]; 6 int val[M]; 7 void build(int L,int R,int rt){ 8 tree[rt]=R-L+1; 9 if(L!=R){ 10 int mid=(L+R)>>1; 11 build(L,mid,rt<<1); 12 build(mid+1,R,rt<<1|1); 13 } 14 } 15 int update(int x,int L,int R,int rt){ 16 tree[rt]--; 17 if(L==R){ 18 return L; 19 } 20 int mid=(L+R)>>1; 21 if(tree[rt<<1]>=x){ 22 return update(x,L,mid,rt<<1); 23 } 24 else{ 25 x-=tree[rt<<1]; 26 return update(x,mid+1,R,rt<<1|1); 27 } 28 } 29 int main(){ 30 int n; 31 while(~scanf("%d",&n)){ 32 build(1,n,1); 33 for(int i=1;i<=n;i++){ 34 scanf("%d%d",&pos[i],&val[i]); 35 } 36 for(int i=n;i>=1;i--){ 37 int k=update(pos[i]+1,1,n,1); 38 ans[k]=val[i]; 39 } 40 for(int i=1;i<=n;i++){ 41 printf("%d ",ans[i]); 42 } 43 puts(""); 44 } 45 return 0; 46 }
poj 3468blog
區間+值,區間求和,線段樹區間更新基礎。
1 //#define debug 2 //#define txtout 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<stack> 13 #include<queue> 14 #include<set> 15 #include<map> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double eps=1e-8; 20 const double pi=acos(-1.0); 21 const int inf=0x3f3f3f3f; 22 const int M=1e5+10; 23 class SegmentTree{ 24 #define lrrt int L,int R,int rt 25 #define iall 1,n,1 26 #define imid int mid=(L+R)>>1 27 #define lson L,mid,rt<<1 28 #define rson mid+1,R,rt<<1|1 29 static const int MV=1e5+10; 30 struct T{ 31 LL sum,lazy; 32 }tree[MV<<2]; 33 int n; 34 void build(lrrt,int a[]){ 35 tree[rt].lazy=0; 36 if(L==R){ 37 tree[rt].sum=a[L]; 38 return ; 39 } 40 imid; 41 build(lson,a); 42 build(rson,a); 43 pushup(rt); 44 } 45 void pushup(int rt){ 46 tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; 47 } 48 void pushdown(int mid,lrrt){ 49 if(tree[rt].lazy){ 50 tree[rt<<1].sum+=tree[rt].lazy*(mid-L+1); 51 tree[rt<<1|1].sum+=tree[rt].lazy*(R-mid); 52 tree[rt<<1].lazy+=tree[rt].lazy; 53 tree[rt<<1|1].lazy+=tree[rt].lazy; 54 tree[rt].lazy=0; 55 } 56 } 57 void update(int x,int y,LL z,lrrt){ 58 if(x<=L&&R<=y){ 59 tree[rt].sum+=(R-L+1)*z; 60 tree[rt].lazy+=z; 61 return ; 62 } 63 imid; 64 pushdown(mid,L,R,rt); 65 if(mid>=x) update(x,y,z,lson); 66 if(mid<y) update(x,y,z,rson); 67 pushup(rt); 68 } 69 LL querySum(int x,int y,lrrt){ 70 if(x<=L&&R<=y) return tree[rt].sum; 71 imid; 72 pushdown(mid,L,R,rt); 73 LL sum=0; 74 if(mid>=x) sum+=querySum(x,y,lson); 75 if(mid<y) sum+=querySum(x,y,rson); 76 return sum; 77 } 78 public: 79 void init(int tn,int a[]){ 80 n=tn; 81 build(iall,a); 82 } 83 void update(int x,int y,LL z){ 84 update(x,y,z,iall); 85 } 86 LL querySum(int x,int y){ 87 return querySum(x,y,iall); 88 } 89 }st; 90 int n,m; 91 int a[M]; 92 vector<LL> answer; 93 struct Q{ 94 int x,y,z; 95 char type[4]; 96 }q[M]; 97 void solve(){ 98 st.init(n,a); 99 answer.clear(); 100 for(int i=0;i<m;i++){ 101 if(q[i].type[0]=='Q'){ 102 answer.push_back(st.querySum(q[i].x,q[i].y)); 103 continue; 104 } 105 st.update(q[i].x,q[i].y,q[i].z); 106 } 107 } 108 int main() { 109 #ifdef txtout 110 freopen("in.txt","r",stdin); 111 freopen("out.txt","w",stdout); 112 #endif // txtout 113 while(~scanf("%d%d",&n,&m)) { 114 for(int i=1; i<=n; i++) { 115 scanf("%d",&a[i]); 116 } 117 for(int i=0;i<m;i++){ 118 scanf("%s%d%d",q[i].type,&q[i].x,&q[i].y); 119 if(q[i].type[0]=='C'){ 120 scanf("%d",&q[i].z); 121 } 122 } 123 solve(); 124 for(int i=0; i<answer.size(); i++) { 125 printf("%I64d\n",answer[i]); 126 } 127 } 128 return 0; 129 }
poj 2528
區間賦值,查詢有多少個不一樣的值。座標較大須要離散化。線段樹區間賦值,單點查詢基礎。
1 //#define debug 2 //#define txtout 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<stack> 13 #include<queue> 14 #include<set> 15 #include<map> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double eps=1e-8; 20 const double pi=acos(-1.0); 21 const int inf=0x3f3f3f3f; 22 const int M=1e4+10; 23 class SegmentTree{ 24 #define lrrt int L,int R,int rt 25 #define iall 1,n,1 26 #define imid int mid=(L+R)>>1 27 #define lson L,mid,rt<<1 28 #define rson mid+1,R,rt<<1|1 29 static const int MV=1e5+10; 30 struct T{ 31 int sum,cover; 32 }tree[MV<<2]; 33 int n; 34 void build(lrrt){ 35 tree[rt].sum=0; 36 tree[rt].cover=0; 37 if(L==R) return ; 38 imid; 39 build(lson); 40 build(rson); 41 } 42 void pushdown(int mid,lrrt){ 43 if(tree[rt].cover){ 44 tree[rt<<1].cover=tree[rt].cover; 45 tree[rt<<1|1].cover=tree[rt].cover; 46 tree[rt<<1].sum=tree[rt].cover*(mid-L+1); 47 tree[rt<<1|1].sum=tree[rt].cover*(R-mid); 48 tree[rt].cover=0; 49 } 50 } 51 void change(int x,int y,int z,lrrt){ 52 if(x<=L&&R<=y){ 53 tree[rt].sum=(R-L+1)*z; 54 tree[rt].cover=z; 55 return ; 56 } 57 imid; 58 pushdown(mid,L,R,rt); 59 if(mid>=x) change(x,y,z,lson); 60 if(mid<y) change(x,y,z,rson); 61 } 62 int querySum(int x,int y,lrrt){ 63 if(x<=L&&R<=y) return tree[rt].sum; 64 imid; 65 pushdown(mid,L,R,rt); 66 int sum=0; 67 if(mid>=x) sum+=querySum(x,y,lson); 68 if(mid<y) sum+=querySum(x,y,rson); 69 return sum; 70 } 71 public: 72 void init(int tn){ 73 n=tn; 74 build(iall); 75 } 76 void change(int x,int y,int z){ 77 change(x,y,z,iall); 78 } 79 int querySum(int x,int y){ 80 return querySum(x,y,iall); 81 } 82 }st; 83 int n; 84 struct A{ 85 int x,y; 86 }a[M]; 87 map<int,int> mp; 88 vector<int> buffer; 89 void init_map(){ 90 buffer.clear(); 91 for(int i=0;i<n;i++){ 92 buffer.push_back(a[i].x); 93 buffer.push_back(a[i].y); 94 } 95 sort(buffer.begin(),buffer.end()); 96 mp.clear(); 97 int id=1; 98 for(int i=0;i<buffer.size();i++){ 99 if(mp.count(buffer[i])) continue; 100 mp[buffer[i]]=id++; 101 } 102 } 103 int solve(){ 104 init_map(); 105 int total=mp.size(); 106 st.init(total); 107 for(int i=0;i<n;i++){ 108 st.change(mp[a[i].x],mp[a[i].y],i+1); 109 } 110 buffer.clear(); 111 for(int i=1;i<=total;i++){ 112 buffer.push_back(st.querySum(i,i)); 113 } 114 sort(buffer.begin(),buffer.end()); 115 buffer.push_back(-1); 116 int answer=0; 117 for(int i=0;i+1<buffer.size();i++){ 118 if(buffer[i]!=buffer[i+1]){ 119 answer++; 120 } 121 } 122 return answer; 123 } 124 int main(){ 125 #ifdef txtout 126 freopen("in.txt","r",stdin); 127 freopen("out.txt","w",stdout); 128 #endif // txtout 129 int t; 130 while(~scanf("%d",&t)){ 131 while(t--){ 132 scanf("%d",&n); 133 for(int i=0;i<n;i++){ 134 scanf("%d%d",&a[i].x,&a[i].y); 135 } 136 printf("%d\n",solve()); 137 } 138 } 139 return 0; 140 }
上面代碼雖能ac,但實際上有錯,不知道poj樣例水了? 15 ,12,45,這一組答案應是3, 上面代碼返回2, 緣由是離散化有問題. 下面給13年的代碼, 離散化的時候注意兩個點不相鄰的時候, 離散化後也應該不相鄰,增長一箇中間值就行.
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int M=10000010; 5 int myset[M]; 6 int mymap[M]; 7 bool v[M]; 8 int lazy[M<<2]; 9 struct G{ 10 int x,y; 11 }g[10010]; 12 void build(int L,int R,int rt){ 13 lazy[rt]=0; 14 if(L==R){ 15 return ; 16 } 17 int mid=(L+R)>>1; 18 build(L,mid,rt<<1); 19 build(mid+1,R,rt<<1|1); 20 } 21 void pushdown(int rt){ 22 if(lazy[rt]){ 23 if(lazy[rt<<1]<lazy[rt]) 24 lazy[rt<<1]=lazy[rt]; 25 if(lazy[rt<<1|1]<lazy[rt]) 26 lazy[rt<<1|1]=lazy[rt]; 27 lazy[rt]=0; 28 } 29 } 30 void update(int x,int y,int val,int L,int R,int rt){ 31 if(x<=L&&R<=y){ 32 if(lazy[rt]<val) 33 lazy[rt]=val; 34 } 35 else{ 36 int mid=(L+R)>>1; 37 pushdown(rt); 38 if(mid>=x) 39 update(x,y,val,L,mid,rt<<1); 40 if(mid<y) 41 update(x,y,val,mid+1,R,rt<<1|1); 42 } 43 } 44 void get(int L,int R,int rt){ 45 if(L==R){ 46 v[lazy[rt]]=true; 47 } 48 else{ 49 int mid=(L+R)>>1; 50 pushdown(rt); 51 get(L,mid,rt<<1); 52 get(mid+1,R,rt<<1|1); 53 } 54 } 55 int main(){ 56 int t,n,m; 57 while(~scanf("%d",&t)){ 58 while(t--){ 59 scanf("%d",&m); 60 int ls=0; 61 for(int i=0;i<m;i++){ 62 scanf("%d%d",&g[i].x,&g[i].y); 63 myset[ls++]=g[i].x; 64 myset[ls++]=g[i].y; 65 } 66 sort(myset,myset+ls); 67 int id=0; 68 myset[ls]=0; 69 for(int i=0;i<ls;i++){ 70 if(myset[i]!=myset[i+1]){ 71 myset[id++]=myset[i]; 72 } 73 } 74 ls=id; 75 myset[ls]=0; 76 n=1; 77 for(int i=0;i<ls;i++,n++){ 78 mymap[myset[i]]=n; 79 if(myset[i+1]!=myset[i]+1){ 80 n++; 81 } 82 } 83 build(1,n,1); 84 int val=1; 85 for(int i=0;i<m;i++,val++){ 86 update(mymap[g[i].x],mymap[g[i].y],val,1,n,1); 87 } 88 for(int i=1;i<=val;i++){ 89 v[i]=false; 90 } 91 get(1,n,1); 92 int ans=0; 93 for(int i=1;i<=val;i++){ 94 if(v[i]){ 95 ans++; 96 } 97 } 98 printf("%d\n",ans); 99 } 100 } 101 return 0; 102 }
poj 3667
酒店有n個房間,開始都空, 每次來個團, 她們要求要連續的k個房間,不存在輸出0, 存在就把起點最靠左邊的輸出,並佔用這一段房間. 線段樹, 一開始全1 ,表示每一個房間均可用, 更新就是區間賦值1或0.
線段樹4個值,big是該區間最大連續子段的長度, left是區間左端點爲起點的最長連續子段長度, right是右端點爲終點, cover是區間賦值的延遲標記. 一個區間最長可能有3種狀況 ,徹底在左兒子, 徹底在右兒子, 左兒子的right + 右兒子的left.
1 //#define txtout 2 //#define debug 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<stack> 13 #include<queue> 14 #include<set> 15 #include<map> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double pi=acos(-1.0); 20 const double eps=1e-8; 21 const int inf=0x3f3f3f3f; 22 const int M=5e4+10; 23 class SegmentTree{ 24 #define lrrt int L,int R,int rt 25 #define iall 1,n,1 26 #define imid int mid=(L+R)>>1 27 #define lson L,mid,rt<<1 28 #define rson mid+1,R,rt<<1|1 29 static const int MV=5e4+10; 30 struct T{ 31 int big,left,right,cover; 32 }tree[MV<<2]; 33 int n; 34 void pushup(int mid,lrrt){ 35 tree[rt].big=max(tree[rt<<1].big,tree[rt<<1|1].big); 36 tree[rt].big=max(tree[rt].big,tree[rt<<1].right+tree[rt<<1|1].left); 37 tree[rt].left=tree[rt<<1].left; 38 if(tree[rt].left==mid-L+1){ 39 tree[rt].left+=tree[rt<<1|1].left; 40 } 41 tree[rt].right=tree[rt<<1|1].right; 42 if(tree[rt].right==R-mid){ 43 tree[rt].right+=tree[rt<<1].right; 44 } 45 } 46 void build(lrrt){ 47 tree[rt].cover=-1; 48 if(L==R){ 49 tree[rt].big=1; 50 tree[rt].left=1; 51 tree[rt].right=1; 52 return ; 53 } 54 imid; 55 build(lson); 56 build(rson); 57 pushup(mid,L,R,rt); 58 } 59 void pushdown(int mid,lrrt){ 60 if(tree[rt].cover!=-1){ 61 tree[rt<<1].cover=tree[rt].cover; 62 tree[rt<<1|1].cover=tree[rt].cover; 63 int lvalue=(mid-L+1)*tree[rt].cover; 64 tree[rt<<1].big=lvalue; 65 tree[rt<<1].left=lvalue; 66 tree[rt<<1].right=lvalue; 67 int rvalue=(R-mid)*tree[rt].cover; 68 tree[rt<<1|1].big=rvalue; 69 tree[rt<<1|1].left=rvalue; 70 tree[rt<<1|1].right=rvalue; 71 tree[rt].cover=-1; 72 } 73 } 74 void update(int x,int y,int z,lrrt){ 75 if(x<=L&&R<=y){ 76 tree[rt].cover=z; 77 int value=(R-L+1)*z; 78 tree[rt].big=value; 79 tree[rt].left=value; 80 tree[rt].right=value; 81 return ; 82 } 83 imid; 84 pushdown(mid,L,R,rt); 85 if(mid>=x) update(x,y,z,lson); 86 if(mid<y) update(x,y,z,rson); 87 pushup(mid,L,R,rt); 88 } 89 int query(int x,lrrt){ 90 if(L==R) return L; 91 imid; 92 pushdown(mid,L,R,rt); 93 if(tree[rt<<1].big>=x) return query(x,lson); 94 if(tree[rt<<1].right+tree[rt<<1|1].left>=x) return mid-tree[rt<<1].right+1; 95 return query(x,rson); 96 } 97 public: 98 void init(int tn){ 99 n=tn; 100 build(iall); 101 } 102 int query(int len){ 103 if(tree[1].big<len) return 0; 104 return query(len,iall); 105 } 106 void update(int x,int y,int z){ 107 update(x,y,z,iall); 108 } 109 }st; 110 int n,m; 111 struct Q{ 112 int type,x,y; 113 }q[M]; 114 vector<int> answer; 115 void solve(){ 116 st.init(n); 117 answer.clear(); 118 for(int i=0;i<m;i++){ 119 if(q[i].type==1){ 120 int result=st.query(q[i].x); 121 answer.push_back(result); 122 if(result){ 123 st.update(result,result+q[i].x-1,0); 124 } 125 continue; 126 } 127 st.update(q[i].x,q[i].x+q[i].y-1,1); 128 } 129 } 130 int main() { 131 #ifdef txtout 132 freopen("in.txt","r",stdin); 133 freopen("out.txt","w",stdout); 134 #endif // txtout 135 while(~scanf("%d%d",&n,&m)) { 136 for(int i=0; i<m; i++) { 137 scanf("%d%d",&q[i].type,&q[i].x); 138 if(q[i].type==2){ 139 scanf("%d",&q[i].y); 140 } 141 } 142 solve(); 143 for(int i=0; i<answer.size(); i++) { 144 printf("%d\n",answer[i]); 145 } 146 } 147 return 0; 148 }
處理特殊圖
poj 1041 uva302
poj 2337 zoj 1919
uva 216
uva 10944
poj 1776 zoj 2359 uva 2954
poj 1419 uva 193
poj 1144 zoj 1311 uva 315
poj 3352
相關題庫
poj 2774
poj 3261
poj 2777
一開始n個點都是顏色1, 操做會把某一個區間的顏色都變成 z, 查詢某個區間有多少種不一樣顏色. 如今的寫法, 由於顏色只有30位, 一開始開了30個線段樹分別存某種顏色, 對於某個顏色的某個位置, 要麼是, 要麼不是, 超時了, 用二進制每一位表示每一個顏色, 1表示有, 0表示沒有這個顏色, 合併就是或操做了. 查詢就是查1的個數了.
1 //#define txtout 2 //#define debug 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<stack> 13 #include<queue> 14 #include<set> 15 #include<map> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double pi=acos(-1.0); 20 const double eps=1e-8; 21 const int inf=0x3f3f3f3f; 22 const int M=1e5+10; 23 class SegmentTree{ 24 #define lrrt int L,int R,int rt 25 #define iall 1,n,1 26 #define imid int mid=(L+R)>>1 27 #define lson L,mid,rt<<1 28 #define rson mid+1,R,rt<<1|1 29 static const int MV=1e5+10; 30 struct T{ 31 int value; 32 int cover; 33 }tree[MV<<2]; 34 int n; 35 void pushup(int rt){ 36 tree[rt].value=tree[rt<<1].value|tree[rt<<1|1].value; 37 } 38 void build(lrrt){ 39 tree[rt].cover=-1; 40 tree[rt].value=1; 41 if(L==R) return ; 42 imid; 43 build(lson); 44 build(rson); 45 } 46 void pushdown(int rt){ 47 if(tree[rt].cover!=-1){ 48 tree[rt<<1].cover=tree[rt].cover; 49 tree[rt<<1|1].cover=tree[rt].cover; 50 tree[rt<<1].value=tree[rt].cover; 51 tree[rt<<1|1].value=tree[rt].cover; 52 tree[rt].cover=-1; 53 } 54 } 55 void update(int x,int y,int z,lrrt){ 56 if(x<=L&&R<=y){ 57 tree[rt].cover=1<<(z-1); 58 tree[rt].value=1<<(z-1); 59 return ; 60 } 61 imid; 62 pushdown(rt); 63 if(mid>=x) update(x,y,z,lson); 64 if(mid<y) update(x,y,z,rson); 65 pushup(rt); 66 } 67 int query(int x,int y,lrrt){ 68 if(x<=L&&R<=y) return tree[rt].value; 69 imid; 70 pushdown(rt); 71 int result=0; 72 if(mid>=x) result|=query(x,y,lson); 73 if(mid<y) result|=query(x,y,rson); 74 return result; 75 } 76 public: 77 void init(int tn){ 78 n=tn; 79 build(iall); 80 } 81 int query(int x,int y){ 82 return query(x,y,iall); 83 } 84 void update(int x,int y,int z){ 85 update(x,y,z,iall); 86 } 87 }st; 88 int n,t,m; 89 struct Q{ 90 int x,y,z; 91 char type[4]; 92 }q[M]; 93 vector<int> answer; 94 void solve(){ 95 st.init(n); 96 answer.clear(); 97 for(int i=0;i<m;i++){ 98 if(q[i].x>q[i].y) swap(q[i].x,q[i].y); 99 if(q[i].type[0]=='C'){ 100 st.update(q[i].x,q[i].y,q[i].z); 101 continue; 102 } 103 int sum=0; 104 int result=st.query(q[i].x,q[i].y); 105 for(int j=0;j<t;j++){ 106 if((result>>j)&1) sum++; 107 } 108 answer.push_back(sum); 109 } 110 } 111 int main() { 112 #ifdef txtout 113 freopen("in.txt","r",stdin); 114 freopen("out.txt","w",stdout); 115 #endif // txtout 116 while(~scanf("%d%d%d",&n,&t,&m)) { 117 for(int i=0; i<m; i++) { 118 scanf("%s%d%d",q[i].type,&q[i].x,&q[i].y); 119 if(q[i].type[0]=='C'){ 120 scanf("%d",&q[i].z); 121 } 122 } 123 solve(); 124 for(int i=0; i<answer.size(); i++) { 125 printf("%d\n",answer[i]); 126 } 127 } 128 return 0; 129 }
13年寫的, 是若是一個區間都是一個顏色, 就是這個顏色, 不然爲0, 查詢時 遇到一個區間是同一種顏色的 ,直接返回, 不然暴力搜 . 顏色比較少, 可能樣例水吧 這麼作也能過, 複雜度很差估計.
1 #include<cstdio> 2 #define lson L,mid,rt<<1 3 #define rson mid+1,R,rt<<1|1 4 const int M=100010; 5 int tree[M<<2],lazy[M<<2]; 6 bool v[64]; 7 void pushup(int rt){ 8 if(tree[rt<<1]==tree[rt<<1|1]){ 9 tree[rt]=tree[rt<<1]; 10 } 11 else{ 12 tree[rt]=0; 13 } 14 } 15 void build(int L,int R,int rt){ 16 lazy[rt]=0; 17 tree[rt]=1; 18 if(L==R){ 19 return ; 20 } 21 int mid=(L+R)>>1; 22 build(lson); 23 build(rson); 24 } 25 void pushdown(int rt){ 26 if(lazy[rt]){ 27 lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt]; 28 tree[rt]=tree[rt<<1]=tree[rt<<1|1]=lazy[rt]; 29 lazy[rt]=0; 30 } 31 } 32 void update(int x,int y,int z,int L,int R,int rt){ 33 if(x<=L&&R<=y){ 34 lazy[rt]=z; 35 tree[rt]=z; 36 return ; 37 } 38 int mid=(L+R)>>1; 39 pushdown(rt); 40 if(mid>=x) 41 update(x,y,z,lson); 42 if(mid<y) 43 update(x,y,z,rson); 44 pushup(rt); 45 } 46 void query(int x,int y,int L,int R,int rt){ 47 if(x<=L&&R<=y){ 48 if(tree[rt]){ 49 v[tree[rt]]=true; 50 return ; 51 } 52 } 53 int mid=(L+R)>>1; 54 pushdown(rt); 55 if(mid>=x) 56 query(x,y,lson); 57 if(mid<y) 58 query(x,y,rson); 59 } 60 int main(){ 61 int n,t,m; 62 while(~scanf("%d%d%d",&n,&t,&m)){ 63 build(1,n,1); 64 while(m--){ 65 int a,b,c; 66 char s[4]; 67 scanf("%s%d%d",s,&a,&b); 68 if(a>b){ 69 int temp=a; 70 a=b; 71 b=temp; 72 } 73 if(s[0]=='C'){ 74 scanf("%d",&c); 75 update(a,b,c,1,n,1); 76 } 77 else{ 78 for(int i=1;i<=t;i++){ 79 v[i]=false; 80 } 81 int ans=0; 82 query(a,b,1,n,1); 83 for(int i=1;i<=t;i++){ 84 if(v[i]){ 85 ans++; 86 } 87 } 88 printf("%d\n",ans); 89 } 90 } 91 } 92 return 0; 93 }
poj 2886
poj 3225
poj 1436,zoj 1391, uva 2441
poj 2991
poj 1308, zoj 1268 ,uva 615
uva 117
uva 10735
uva 10054 uva 2036
uva 10818
uva 10937