洛谷P1558 色板游戏
題目背景
阿寶上學了,今天老師拿來了一塊很長的涂色板。
題目描述
色板長度為\(L\),\(L\)是一個正整數,所以我們可以均勻地將它劃分成\(L\)塊\(1\)厘米長的小方格。并從左到右標記為\(1, 2, ... L\)。
現在色板上只有一個顏色,老師告訴阿寶在色板上只能做兩件事:
學校的顏料盒中一共有 \(T\) 種顏料。為簡便起見,我們把他們標記為 \(1, 2, ... T\). 開始時色板上原有的顏色就為\(1\)號色。 面對如此復雜的問題,阿寶向你求助,你能幫助他嗎?
輸入輸出格式
輸入格式:
第一行有\(3\)個整數 \(L (1 \leq L \leq 100000)\), \(T (1 \leq T \leq 30)\) 和 \(O (1 \leq O \leq 100000)\)。 在這里\(O\)表示事件數。
接下來 \(O\) 行, 每行以 "\(C\) \(A\) \(B\) \(C\)" 或 "\(P\) \(A\) \(B\)" 得形式表示所要做的事情(這里 \(A\), \(B\), \(C\) 為整數, 可能\(A\)> \(B\),這樣的話需要你交換\(A\)和\(B\))
輸出格式:
對于老師的提問,做出相應的回答。每行一個整數。
輸入輸出樣例
輸入樣例#1:
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2輸出樣例#1:
2 1思路:正解貌似是基于二進制來建線段樹,但是我不會……于是我就非常暴力的建了\(t\)棵線段樹,因為\(t\)只有\(30\)嘛,所以建\(30\)棵線段樹也不會爆,沒棵線段樹代表一個顏色,然后對于每一個\(C\)操作,就是修改要修改的那個顏色的對應線段樹的對應修改區間為\(1\),其余線段樹的對應修改區間修改為\(0\),然后查詢就是把每棵線段樹的區間顏色數加起來。但是代碼可能因為常數優化的不太好等原因,不開\(O(2)\)會\(TLE\)一個點。
代碼:
#include<cstdio> #include<algorithm> #define maxn 100007 #define ls rt<<1 #define rs rt<<1|1 #define re register using namespace std; int n,t,m,sum[31][maxn<<2],lazy[31][maxn<<2]; char s[2]; inline void pushup(int i, int rt) {sum[i][rt]=sum[i][ls]+sum[i][rs]; } inline void pushdown(int i, int rt) {if(lazy[i][rt]==-1) {sum[i][ls]=sum[i][rs]=0;lazy[i][ls]=lazy[i][rs]=-1; }else {lazy[i][ls]=lazy[i][rs]=lazy[i][rt];sum[i][ls]=sum[i][rs]=lazy[i][rt];}lazy[i][rt]=0; } void build(int rt, int l, int r) {if(l==r) {sum[1][rt]=1;return;}int mid=(l+r)>>1;build(ls,l,mid);build(rs,mid+1,r);pushup(1,rt); } void modify(int i, int rt, int l, int r, int L, int R, int val) {if(L>r||R<l) return;if(L<=l&&r<=R) {sum[i][rt]=val;if(!val) lazy[i][rt]=-1;else lazy[i][rt]=val;return;}if(lazy[i][rt]) pushdown(i,rt);int mid=(l+r)>>1;if(L<=mid) modify(i,ls,l,mid,L,R,val);if(R>mid) modify(i,rs,mid+1,r,L,R,val);pushup(i,rt); } int csum(int i, int rt, int l, int r, int L, int R) {if(L>r||R<l) return 0;if(L<=l&&r<=R) return sum[i][rt];if(lazy[i][rt]) pushdown(i,rt);int mid=(l+r)>>1;return csum(i,ls,l,mid,L,R)+csum(i,rs,mid+1,r,L,R); } int main() {scanf("%d%d%d",&n,&t,&m);build(1,1,n);for(re int i=1,l,r,v;i<=m;++i) {scanf("%s%d%d",s,&l,&r);if(l>r) swap(l,r);if(s[0]=='C') {scanf("%d",&v);for(re int k=1;k<=t;++k) {if(k!=v) modify(k,1,1,n,l,r,0);else modify(k,1,1,n,l,r,1);}}else {int zrj=0;for(re int k=1;k<=t;++k) if(csum(k,1,1,n,l,r)) zrj++;printf("%d\n",zrj);}}return 0; }轉載于:https://www.cnblogs.com/grcyh/p/10172894.html
總結
以上是生活随笔為你收集整理的洛谷P1558 色板游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java微博爬虫
- 下一篇: git 中文乱码配置