[校內模擬] 200617Practice CQOI 2018

T1 Android

狀壓DP
不會,咕

T2 Baguenaudier

我有一個九連環,但是從來沒玩過,初中的時候無聊看玩法說明,看到一句話:考慮先拆掉最遠(最靠左)的環
這句話救了今天的我

nn連環需要ana_n次打開
考慮後n2n-2個環,an2a_{n-2}次打開,此時環可以表示爲11000011000\cdots0
拆掉第一個得到01000001000\cdots0
倒着把後n2n-2個環加回來011110111\cdots1
現在就只需要an1a_{n-1}次就可以打開後n1n-1個環了

於是得到遞推式an=an1+2an2+1a_n=a_{n-1}+2a_{n-2}+1
並且發現了奇偶規律:
an={2an1,nmod  2=0,2an1+1,nmod  2=1. a_n=\left\{ \begin{aligned} &2a_{n-1}, && n\mod2=0,\\ &2a_{n-1}+1, && n\mod2=1. \end{aligned} \right.

機房大佬提供了好多種做法,我們繼續推柿子

  1. 蒲巨
    蒲巨前面的推導有點日龍,太複雜了點(他設了好幾個變量,對於他還好,但是對於我這種一見一堆變量名就頭暈的菜雞來說簡直是天書)
    不過有一個好處就是可以迅速發現規律:
    ana_n轉化爲二進制,發現nmod  2=1n\mod2=1時,an=(10101101)2a_n=(10101\cdots 101)_2nmod  2=0n\mod2=0an=(1010110)2a_n=(10101\cdots 10)_2,且這些數的位數都是nn
    二進制+高精=AC

  2. stc wss
    他說這是他網課時被蘇老唯一一次抽起來回答問題的題。。。
    奇數項抽出來an=4an2+1, nOdda_n=4a_{n-2}+1,\ n\in \mathrm{Odd},記爲{bn}\{b_n\},則bn=4n13b_n=\frac{4^n-1}{3}
    高精+快速冪=AC

  3. sto sj
    蘇老,對不起,這是你上課講過的,我數學沒學好,sj哥哥太巨了
    an=an+1+2an+2+1an+an+1=2(an+1+an+2)+1an+an1=2n1 \begin{aligned} &a_n=a_{n+1}+2a_{n+2}+1\\ \Rightarrow&a_n+a_{n+1}=2(a_{n+1}+a_{n+2})+1\\ \Rightarrow&a_n+a_{n-1}=2^n-1 \end{aligned}
    大概這樣
    高精+快速冪=AC

幾種方法最後得到的都是ai=2i+13a_i=\lfloor\frac{2^{i+1}}{3}\rfloor

考場上高精寫炸了,就只有暴力分(不會高精度但會FFT的菜雞感到很淦)
所以就咕了

T3 Xor

莫隊,前綴和

考慮aa的前綴和pp,有
i=lrai=pl1pr=k \bigoplus_{i=l}^ra_i=p_{l-1}\oplus p_r=k

考慮
pl1pr=kpl1=kpr p_{l-1}\oplus p_r=k \Rightarrow p_{l-1}=k\oplus p_r
莫隊可以統計
開個數組記錄區間內不同前綴和的個數

關於莫隊的區間修改,考慮加入一個點,那麼要加入這個點與區間內所有點的關係,再統計這個點,(因爲這個點還不在區間裏面);刪去點反之

莫隊是對左節點(left)分塊!!

#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define re register
inline int in{
	int i=0,f=1;char ch=0;
	while(ch!='-'&&!isdigit(ch)) ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int NNN=5e5+5;
int n,m,k,siz;
int p[NNN];//prefix
int cnt[NNN];//count of each exclusive or sum in each section
int num[NNN];//record ans of each query

struct Query{
	int l,r,id,pos;
}q[NNN];

inline bool cmp1(const Query u,const Query v){
	if(u.pos!=v.pos) return u.pos<v.pos;
	return u.r<v.r;
}

int main(){
	n=in,m=in,k=in,siz=sqrt(n);
	for(re int i=1;i<=n;++i) p[i]=p[i-1]^in;
	for(re int i=1;i<=m;++i){
		q[i].l=in-1;
		q[i].r=in;
		q[i].id=i;
		q[i].pos=(q[i].l-1)/siz+1;
	}
	sort(q+1,q+m+1,cmp1);
	
	re int l=1,r=0,ans=0;
	for(re int i=1;i<=m;++i){
		while(l<q[i].l){
			--cnt[p[l]];
			ans-=cnt[p[l]^k];
			++l;
		}
		while(l>q[i].l){
			--l;
			ans+=cnt[p[l]^k];
			++cnt[p[l]];
		}
		while(r<q[i].r){
			++r;
			ans+=cnt[p[r]^k];
			++cnt[p[r]];
		}
		while(r>q[i].r){
			--cnt[p[r]];
			ans-=cnt[p[r]^k];
			--r;
		}
		num[q[i].id]=ans;
	}
	
	for(re int i=1;i<=m;++i)
		printf("%d\n",num[i]);
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章