中國石油大學(華東)暑期集訓--二進制(BZOJ5294)【線段樹】

問題 C: 二進制

時間限制: 1 Sec??內存限制: 128 MB
提交: 8??解決: 2
[提交] [狀態] [討論版] [命題人:]

題目描述

pupil發現對于一個十進制數,無論怎么將其的數字重新排列,均不影響其是不是3的倍數。他想研究對于二進制,是否也有類似的性質。于是他生成了一個長為n的二進制串,希望你對于這個二進制串的一個子區間,能求出其有多少位置不同的連續子串,滿足在重新排列后(可包含前導0)是一個3的倍數。兩個位置不同的子區間指開始位置不同或結束位置不同。由于他想嘗試盡量多的情況,他有時會修改串中的一個位置,并且會進行多次詢問。

輸入

輸入第一行包含一個正整數n,表示二進制數的長度。
之后一行n個空格隔開的整數,保證均是0或1,表示該二進制串。
之后一行一個整數m,表示詢問和修改的總次數。
之后m行每行為1 i,表示pupil修改了串的第i個位置(0變成1或1變成0),或2 l r,表示pupil詢問的子區間是[l,r]。
串的下標從1開始。

輸出

對于每次詢問,輸出一行一個整數表示對應該詢問的結果。


樣例輸入

4
1 0 1 0
3
2 1 3
1 3
2 3 4

樣例輸出

2
3

提示

對于第一個詢問,區間[2,2]只有數字0,是3的倍數,區間[1,3]可以重排成011(2)=3(10),是3的倍數,其他區間均不能重排成3的倍數。
對于第二個詢問,全部三個區間均能重排成3的倍數(注意00也是合法的)。

對于20%的數據,1≤n,m≤100;
對于50%的數據,1≤n,m≤5000;
對于100%的數據,1≤n,m≤100000,l≤r。


Solution:
設cnt0,cnt1分別為[l,r]區間內的1和0的個數,易得:
1. if cnt1==1 => 不可整除3
2. if cnt1&1 and cnt0<2 => 不可整除3

  簡單證明上述結論:

    顯然結論1是成立的(1<<n不可能整除3),當cnt1為偶數時,顯然也一定可以整除3,而當cnt1&1時:

    先考慮這種情況,將一個二進制數將其兩位兩位拆分并求和得到sum,顯然如果 sum%3==0 ,則該二進制數的十進制一定可以整除3。

    如:111010001=>(01,11,01,00,01),sum=1+3+1+0+1=6。

    那么,對于奇數個1,從中挑出cnt1-3個“1”兩兩組合,確保對sum%3的結果無貢獻后,再看剩下的3個“1”的情況:

      ①、sum(111)=4 無法整除。【區間內無0】

      ②、sum(1101)=4,sum(1011)=5 無法整除。【區間內只含有一個0】

      ③、sum(10101)=3 可整除。【區間內至少含有兩個0】

  綜上:

    我們用線段樹去維護上述兩種不合法情況,再用【總數-不合法數=合法數】來得到答案。

    其中,dl/dr[2][2] 代表經過左右節點后:cnt0=0/1,cnt1&1?1:0。

    fl/fr[3] 代表經過左右節點后:滿足(cnt1==1 and cnt0==0/1)的方案數。

    L/R表示經過左右節點后,連續0的長度。

代碼:

  1 #include <iostream>
  2 #include <string>
  3 #include <cstdio>
  4 #include <cmath>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <vector>
  8 #include <queue>
  9 #include <deque>
 10 #include <map>
 11 #include <set>
 12 #define range(i,a,b) for(auto i=a;i<=b;++i)
 13 #define LL long long
 14 #define ULL unsigned long long
 15 #define elif else if
 16 #define itrange(i,a,b) for(auto i=a;i!=b;++i)
 17 #define rerange(i,a,b) for(auto i=a;i>=b;--i)
 18 #define fill(arr,tmp) memset(arr,tmp,sizeof(arr))
 19 #define IOS ios::sync_with_stdio(false);cin.tie(0)
 20 using namespace std;
 21 int n,m,op,l,r,A[int(1e5+5)];
 22 class SegTree{
 23 private:
 24     struct node{
 25         LL s,dl[2][2],dr[2][2],fl[3],fr[3],L,R;
 26         int cnt0,cnt1;
 27         void reset(){
 28             range(i,0,1)range(j,0,1)dl[i][j]=dr[i][j]=0;
 29             fl[0]=fl[1]=fr[0]=fr[1]=fl[2]=fr[2]=L=R=s=cnt0=cnt1=0;
 30         }
 31         node(){reset();}
 32     }tree[int(1e5+5)<<2];
 33     node comb(node A,node B){
 34         node tmp;
 35         range(i,0,1)range(j,0,1){
 36             tmp.dl[i][j]+=A.dl[i][j];
 37             tmp.dr[i][j]+=B.dr[i][j];
 38             if(i>=A.cnt0)tmp.dl[i][j]+=B.dl[i-A.cnt0][j^(A.cnt1&1)];
 39             if(i>=B.cnt0)tmp.dr[i][j]+=A.dr[i-B.cnt0][j^(B.cnt1&1)];
 40         }
 41         range(i,0,2){
 42             tmp.fl[i]+=A.fl[i];
 43             tmp.fr[i]+=B.fr[i];
 44             if(!A.cnt1)tmp.fl[min(2,i+A.cnt0)]+=B.fl[i];
 45             if(!B.cnt1)tmp.fr[min(2,i+B.cnt0)]+=A.fr[i];
 46         }
 47         if(A.cnt1==1 and B.L){
 48             ++tmp.fl[min(2LL,A.cnt0+B.L)];
 49             tmp.fl[2]+=B.L-1;
 50         }
 51         if(B.cnt1==1 and A.R){
 52             ++tmp.fr[min(2LL,B.cnt0+A.R)];
 53             tmp.fr[2]+=A.R-1;
 54         }
 55         tmp.L=(!A.cnt1?A.cnt0+B.L:A.L);tmp.R=(!B.cnt1?B.cnt0+A.R:B.R);
 56         tmp.cnt0=A.cnt0+B.cnt0;tmp.cnt1=A.cnt1+B.cnt1;tmp.s+=A.s+B.s;
 57         tmp.s+=A.dr[0][1]*(B.dl[1][0]+B.dl[0][0])+A.dr[1][0]*B.dl[0][1];
 58         tmp.s+=A.dr[0][0]*(B.dl[1][1]+B.dl[0][1])+A.dr[1][1]*B.dl[0][0];
 59         if(B.L)tmp.s+=(A.fr[1]+A.fr[2])*B.L+A.fr[0]*(B.L-1);
 60         if(A.R)tmp.s+=(B.fl[1]+B.fl[2])*A.R+B.fl[0]*(A.R-1);
 61         return tmp;
 62     }
 63     void pushup(node &tmp,int x){
 64         tmp.reset();
 65         if(x)tmp.s=tmp.fl[0]=tmp.fr[0]=tmp.dl[0][1]=tmp.dr[0][1]=tmp.cnt1=1;
 66         else tmp.dl[1][0]=tmp.dr[1][0]=tmp.L=tmp.R=tmp.cnt0=1;
 67     };
 68 public:
 69     void build(int l,int r,int rt=1){
 70         if(l==r){
 71             pushup(tree[rt],A[l]);
 72             return;
 73         }
 74         int m=(l+r)>>1;
 75         build(l,m,rt<<1);
 76         build(m+1,r,rt<<1|1);
 77         tree[rt]=comb(tree[rt<<1],tree[rt<<1|1]);
 78     }
 79     void update(int l,int r,int rt,int L){
 80         if(l==r){
 81             pushup(tree[rt],A[l]);
 82             return;
 83         }
 84         int m=(l+r)>>1;
 85         if(L<=m)update(l,m,rt<<1,L);
 86         else update(m+1,r,rt<<1|1,L);
 87         tree[rt]=comb(tree[rt<<1],tree[rt<<1|1]);
 88     }
 89     node query(int l,int r,int rt,int L,int R){
 90         if(L<=l and r<=R)return tree[rt];
 91         int m=(l+r)>>1;
 92         if(R<=m)return query(l,m,rt<<1,L,R);
 93         if(L>m)return query(m+1,r,rt<<1|1,L,R);
 94         return comb(query(l,m,rt<<1,L,m),query(m+1,r,rt<<1|1,m+1,R));
 95     }
 96 }segTree;
 97 void init(){
 98     scanf("%d",&n);
 99     range(i,1,n)scanf("%d",A+i);
100     segTree.build(1,n);
101     scanf("%d",&m);
102 }
103 void solve(){
104     while(m--){
105         scanf("%d%d",&op,&l);
106         if(op&1)A[l]^=1,segTree.update(1,n,1,l);
107         else{
108             scanf("%d",&r);
109             printf("%lld\n",1LL*(r-l+1)*(r-l+2)/2-segTree.query(1,n,1,l,r).s);
110         }
111     }
112 }
113 int main() {
114     init();
115     solve();
116     return 0;
117 }
View Code

?

轉載于:https://www.cnblogs.com/Rhythm-/p/9455281.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388850.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388850.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388850.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2018年10個最佳項目管理工具及鏈接

要在任何業務中取得成功&#xff0c;對項目進行適當的管理非常重要。 項目管理是一系列活動&#xff0c;包括計劃&#xff0c;執行&#xff0c;控制和完成項目。項目管理工具有助于簡化此過程。這里是Best 10項目管理工具及其功能和下載鏈接的精選列表。1&#xff09;AsanaAsan…

Java 8 新特性之Stream API

1. 概述 1.1 簡介 Java 8 中有兩大最為重要的改革&#xff0c;第一個是 Lambda 表達式&#xff0c;另外一個則是 Stream API&#xff08;java.util.stream.*&#xff09;。 Stream 是 Java 8 中處理集合的關鍵抽象概念&#xff0c;它可以指定你希望對集合進行的操作&#xff0c…

[Python設計模式] 第17章 程序中的翻譯官——適配器模式

github地址:https://github.com/cheesezh/python_design_patterns 適配器模式 適配器模式&#xff0c;將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作[DP]。 當系統的數據和行為都正確&#xff0c;但是接口…

Ubuntu中NS2安裝詳細教程

前言&#xff1a; NS2是指 Network Simulator version 2&#xff0c;NS&#xff08;Network Simulator&#xff09; 是一種針對網絡技術的源代碼公開的、免費的軟件模擬平臺&#xff0c;研究人員使用它可以很容易的進行網絡技術的開發&#xff0c;而且發展到今天&#xff0c;它…

es6核心特性圖

轉載于:https://juejin.im/post/5c19e188e51d452db4753925

帶你利用一句話完成轉場動畫

這篇文章主要給大家介紹了關于iOS如何利用一句話完成轉場動畫的相關資料&#xff0c;文中通過示例代碼介紹的非常詳細&#xff0c;對大家的學習或者工作具有一定的參考學習價值&#xff0c;需要的朋友們下面來一起學習學習吧前言本文介紹SS_AnimationTransition 的使用方法,利用…

14.vue路由腳手架

一.vue路由&#xff1a;https://router.vuejs.org/zh/ 1、定義 let router new VueRouter({mode:"history/hash",base:"基本路徑" 加一些前綴 必須在history模式下有效linkActiveClass:"active", 范圍選擇linkExactActiveClass:"exact&qu…

工程師、產品經理、數據工程師是如何一起工作的?

做為一名工程師&#xff0c;免不了與產品經理打交道&#xff0c;如果公司大一些&#xff0c;數據量多一些&#xff0c;還會有數據工程師這個角色。今天會和你主要聊一聊在工作中&#xff0c;產品經理和數據工程師在哪些方面對我們工程師的幫助最大&#xff0c;以及我從他們身上…

linux-buff/cache過大導致內存不足-程序異常

2019獨角獸企業重金招聘Python工程師標準>>> 問題描述 Linux內存使用量超過閾值&#xff0c;使得Java應用程序無可用內存&#xff0c;最終導致程序崩潰。即使在程序沒有掛掉時把程序停掉&#xff0c;系統內存也不會被釋放。 找原因的過程 這個問題已經困擾我好幾個月…

Android 適配(一)

一、Android適配基礎參數1.常見分辨率&#xff08;px&#xff09;oppx 2340x1080oppR15 2280x1080oppor11sp 2160*10801080*1920 (主流屏幕16&#xff1a;9)1080*216018:9 手機主流分辨率&#xff1a; 1080*2160高端 16:9 手機主流分辨率&#xff1a; 1080P (1080*1920) 或 2K …

Source Insight 創建工程(linux-2.6.22.6內核源碼)

1. 軟件設置 安裝完Source Insight&#xff0c;需要對其進行設置添加對“.S”匯編文件的支持&#xff1a; 2. 新建linux-2.6.22.6工程 1&#xff09;選擇工程存放的路徑&#xff1a; 2&#xff09;下載linux-2.6.22.6內核源碼&#xff0c;并解壓。在Source Insight中 指定源碼的…

課時20:內嵌函數和閉包

目錄&#xff1a; 一、global關鍵字 二、內嵌函數 三、閉包 四、課時20課后習題及答案 ******************** 一、global關鍵字 ******************** 全局變量的作用域是整個模塊&#xff08;整個代碼段&#xff09;&#xff0c;也就是代碼段內所有的函數內部都可以訪問到全局…

從零開始學產品第六篇:更強大的測試,自動化測試和性能測試

本篇為【從零開始學產品】系列課第1章第5節歡迎到公眾號菜單欄&#xff0c;獲取產品經理課程更多資料 “測試就是拿點鼠標在電腦上瞎點&#xff0c;或者是用手機隨便戳幾下么&#xff1f;” “不&#xff0c;是有計劃有意圖的測試&#xff0c;比如說&#xff0c;邊界測試&#…

Get 了濾鏡、動畫、AR 特效,速來炫出你的短視頻開發特技!

在濾鏡美顏、搞怪特效、炫酷場景等各種新奇玩法驅動下&#xff0c;短視頻開始讓人上癮。 12 月 3 日&#xff0c;七牛云聯合八大短視頻特效平臺共同推出了中國短視頻開發者創意大賽&#xff08;China Short Video Contest&#xff09;&#xff0c;面向全國邀請廣大開發者&#…

匿名函數、冒泡排序,二分法, 遞歸

匿名函數 lambda 匿名函數 格式 lambda 參數&#xff1a;返回值 函數名統一叫lambda&#xff0c;最多只能寫一行普通的正常的函數 def func(n):return n * n lambda匿名函數寫法 a lambda n : n**2 print(a(3)) 當有多個返回值時suiyi lambda x, y : (1, 2) # 筆試題 …

Redis源碼剖析

Redis源碼剖析和注釋&#xff08;一&#xff09;---鏈表結構 Redis源碼剖析和注釋&#xff08;二&#xff09;--- 簡單動態字符串 Redis源碼剖析和注釋&#xff08;三&#xff09;--- Redis 字典結構 Redis源碼剖析和注釋&#xff08;四&#xff09;--- 跳躍表(skiplist) Redis…

Android Activity生命周期

Android生命周期 Android的生命周期&#xff1a;onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy() 如下圖所示&#xff1a; 1.當activity啟動時系統會先調用onCreate(),然后調用onStart(),最后調用**onResume()**方法&#xff0…

date數據存入mysql_Date對象存入mysql數據庫

java.sql.Date,java.sql.Time和java.sql.Timestamp三個都是java.util.Date的子類(包裝類)。java.sql.Date是java.util.Date的子類&#xff0c;是一個包裝了毫秒值的瘦包裝器&#xff0c;允許 JDBC 將毫秒值標識為 SQL DATE 值。毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以…

盛嚴謹,嚴謹,再嚴謹。_評估員工調查的統計嚴謹性

盛嚴謹,嚴謹,再嚴謹。The human resources industry relies heavily on a wide range of assessments to support its functions. In fact, to ensure unbiased and fair hiring practices the US department of labor maintains a set of guidelines (Uniform Guidelines) to …

復權就是對股價和成交量進行權息修

* 所謂復權就是對股價和成交量進行權息修復,按照股票的實際漲跌繪制股價走勢圖, * 并把成交量調整為相同的股本口徑。股票除權、除息之后&#xff0c;股價隨之產生了變化&#xff0c; * 但實際成本并沒有變化。 * 如&#xff1a;原來20元的股票&#xff0c;十送十之…