P2184 贪婪大陆
題目背景
面對螞蟻們的瘋狂進攻,小FF的Tower defence宣告失敗……人類被螞蟻們逼到了Greed Island上的一個海灣。現在,小FF的后方是一望無際的大海, 前方是變異了的超級螞蟻。 小FF還有大好前程,他可不想命喪于此, 于是他派遣手下最后一批改造SCV布置地雷以阻擋螞蟻們的進攻。
題目描述
小FF最后一道防線是一條長度為N的戰壕, 小FF擁有無數多種地雷,而SCV每次可以在[ L , R ]區間埋放同一種不同于之前已經埋放的地雷。 由于情況已經十萬火急,小FF在某些時候可能會詢問你在[ L' , R'] 區間內有多少種不同的地雷, 他希望你能盡快的給予答復。
對于30%的數據: 0<=n, m<=1000;
對于100%的數據: 0<=n, m<=10^5.
輸入輸出格式
輸入格式:第一行為兩個整數n和m; n表示防線長度, m表示SCV布雷次數及小FF詢問的次數總和。
接下來有m行, 每行三個整數Q,L , R; 若Q=1 則表示SCV在[ L , R ]這段區間布上一種地雷, 若Q=2則表示小FF詢問當前[ L , R ]區間總共有多少種地雷。
輸出格式:對于小FF的每次詢問,輸出一個答案(單獨一行),表示當前區間地雷總數。
輸入輸出樣例
輸入樣例#1:? 5 4 1 1 3 2 2 5 1 2 4 2 3 5 輸出樣例#1:? 1 2?
Solution:
本題要求一段區間雷的個數,等價于求該區間與多少個前面修改過的區間相交。
那么我們用兩個樹狀數組$s,c$,$s$維護節點$i$之前有多少個區間的左端點,$c$維護節點$i$之前有多少個區間的右端點。
則每次修改區間$[x,y]$時,將$s$從$[x,n]$每一位$+1$,將$c$從$[y,n]$每一位$+1$,套用差分的思想只需單點修改即可。查詢區間$[x,y]$時,答案$=$$y$之前的區間左端點個數$-x$之前的區間右端點個數,套用了類似前綴和的思想。
代碼:
?
#include<bits/stdc++.h> #define il inline #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) using namespace std; const int N=1e5+7; int n,m,s[N],c[N]; il int gi(){int a=0;char x=getchar();while(x<'0'||x>'9')x=getchar();while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();return a; } il void update(int k,int x,int *c){while(k<=n){c[k]+=x;k+=k&-k;}} il int query(int x,int *c){int su=0;while(x){su+=c[x];x-=x&-x;}return su;} int main(){n=gi(),m=gi();int f,x,y;For(i,1,m){f=gi(),x=gi(),y=gi();if(f==1){update(x,1,s);update(y,1,c);}else printf("%d\n",query(y,s)-query(x-1,c));}return 0; }?
轉載于:https://www.cnblogs.com/five20/p/9063708.html
總結
以上是生活随笔為你收集整理的P2184 贪婪大陆的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 结巴分词器用法
- 下一篇: thinkphp两表联查并且分页