給定n個硬幣,編號爲0, 1, 2, ......, n-1,都爲反面朝上(即都爲0)。有m次操做,每次將a, b區間內的硬幣翻轉,請輸出翻轉後的硬幣排列。ios
5 2
1 2
2 4數組
10110spa
對於該題,最簡單的作法是模擬,即創建數組s[n],初始化爲0,而後每次將[a, b]上的數字+1,最後順序輸出。若是s[i]爲偶數,則爲0面朝上,不然爲1面朝上。這種作法的修改的時間複雜度爲O(m*n),輸出爲O(n),當m和n都比較大的時候代價難以承受。code
顯然題目要求是對區間進行操做,因此天然而然地想到了樹狀數組或線段樹。通過模擬方法的分析後,發現操做爲區間修改,求單點的值,用樹狀數組或線段樹均可以實現。因爲線段樹的代碼比較複雜,因此選擇樹狀數組。ci
#include<iostream> #include<algorithm> #include<cstring> #include<cmath> #define lowbit(a) (a&(-a)) using namespace std; int n,m; int s[100100]; void add(int x,int c) { for(int i=x;i>0;i-=lowbit(i)) s[i]+=c; } int sum(int x) { int r=0; for(int i=x;i<=n;i+=lowbit(i)) r+=s[i]; return r; } int main() { memset(s,0,sizeof(s)); cin>>n>>m; int a,b; for(int i=1;i<=m;i++) { cin>>a>>b; add(a-1,-1); add(b,1); } for(int i=1;i<=n;i++) { int c=sum(i); cout<<(c&1); } return 0; }