文章目錄
T1 Android
狀壓DP
不會,咕
T2 Baguenaudier
我有一個九連環,但是從來沒玩過,初中的時候無聊看玩法說明,看到一句話:考慮先拆掉最遠(最靠左)的環
這句話救了今天的我
記連環需要次打開
考慮後個環,次打開,此時環可以表示爲
拆掉第一個得到
倒着把後個環加回來
現在就只需要次就可以打開後個環了
於是得到遞推式
並且發現了奇偶規律:
機房大佬提供了好多種做法,我們繼續推柿子
-
蒲巨
蒲巨前面的推導有點日龍,太複雜了點(他設了好幾個變量,對於他還好,但是對於我這種一見一堆變量名就頭暈的菜雞來說簡直是天書)
不過有一個好處就是可以迅速發現規律:
將轉化爲二進制,發現時,;時,且這些數的位數都是
二進制+高精=AC -
stc wss
他說這是他網課時被蘇老唯一一次抽起來回答問題的題。。。
奇數項抽出來,記爲,則
高精+快速冪=AC -
sto sj
蘇老,對不起,這是你上課講過的,我數學沒學好,sj哥哥太巨了
大概這樣
高精+快速冪=AC
幾種方法最後得到的都是
考場上高精寫炸了,就只有暴力分(不會高精度但會FFT的菜雞感到很淦)
所以就咕了
T3 Xor
莫隊,前綴和
考慮的前綴和,有
考慮
莫隊可以統計
開個數組記錄區間內不同前綴和的個數
關於莫隊的區間修改,考慮加入一個點,那麼要加入這個點與區間內所有點的關係,再統計這個點,(因爲這個點還不在區間裏面);刪去點反之
莫隊是對左節點(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;
}