time limit: 8 sec memory limit: 128 mb挺有意思的一道題,應該不難想到是分治fft,主要是cdq分治函式內部要想得很清楚。submit: 578 solved: 202
[submit][status][discuss]
定義二元運算 opt 滿足
現在給定乙個長為 n 的數列 a 和乙個長為 m 的數列 b ,接下來有 q 次詢問。每次詢問給定乙個數字 c
你需要求出有多少對 (i, j) 使得 a_i opt b_j=c 。
第一行是乙個整數 t (1≤t≤10) ,表示測試資料的組數。
對於每組測試資料:
第一行是三個整數 n,m,q (1≤n,m,q≤50000) 。
第二行是 n 個整數,表示 a_1,a_2,?,a_n (0≤a_1,a_2,?,a_n≤50000) 。
第三行是 m 個整數,表示 b_1,b_2,?,b_m (0≤b_1,b_2,?,b_m≤50000) 。
第四行是 q 個整數,第 i 個整數 c_i (0≤c_i≤100000) 表示第 i 次查詢的數。
對於每次查詢,輸出一行,包含乙個整數,表示滿足條件的 (i, j) 對的個數。
22 1 5
1 32
1 2 3 4 5
2 2 5
1 32 4
1 2 3 4 510
1001
0101
鳴謝tangjz提供試題
[submit][status][discuss]
首先如果只有加法,就是裸卷積。
如果只有減法,那麼有$c_k=\sum\limits_^na_ib_$,把b翻轉,最後將c前移n位即可$c_=\sum\limits_^na_b_$
現在有了大小關係的限制,我們可以通過$cdq$分治處理。
首先特判掉相等的情況,然後對於$[l,r]$這個區間,將$[l,mid]$和$[mid+1,r]$遞迴處理,現在問題只剩下$a[l,mid]$和$b[mid+1,r]$,$a[mid+1,r]$和$b[l,mid]$兩個問題了。
顯然前乙個問題直接將$a$前移$l$位,$b$前移$mid+1$位,卷起來之後再後移$l+mid+1$位即可。後乙個問題,將$a$前移$mid+1$位,b翻轉後前移$l$位,這樣卷之後的區間下標是從$0$開始的,而我們的差是從$1$開始的,所以右移$1$位。
卷的時候還是一定要注意次數界!ntt也可以。
1 #include2 #include3 #include4 #include5#define mem(a) memset(a,0,sizeof(a))
6 typedef long
long
ll;7
using
namespace
std;89
const
int n=500010;10
const
double pi=acos(-1
.);11
struct ca[n],b[n];
12int
a[n],b[n],rev[n],n,t,x,m,q,mx,len1,len2;
13ll ans[n];
1415 c operator +(c &a,c &b); }
16 c operator -(c &a,c &b); }
17 c operator *(const c &a,const c &b); }
1819
void dft(c a,int n,int
f);23
for (int p=i<<1,j=0; jp);
25for (int k=0; kwn)28}
29}30if (f==1) return;31
for (int i=0; in;32}
3334
void cdq(int l,int
r);41
for (int i=l; i<=mid; i++) a[i-l].x=a[i];
42for (int i=mid+1; i<=r; i++) b[i-mid-1].x=b[i];
43 dft(a,n,1); dft(b,n,1
);44
for (int i=0; ib[i];
45 dft(a,n,-1
);46
for (int i=0; i1+l]+=(ll)(a[i].x+0.5
);47
48for (int i=0; i0,0
};49
for (int i=mid+1; i<=r; i++) a[i-mid-1].x=a[i];
50for (int i=l; i<=mid; i++) b[mid-i].x=b[i];
51 dft(a,n,1); dft(b,n,1
);52
for (int i=0; ib[i];
53 dft(a,n,-1
);54
for (int i=0; i1]+=(ll)(a[i].x+0.5
);55 cdq(l,mid); cdq(mid+1
,r);56}
5758
intmain()
69return0;
70 }
BZOJ4836 二元運算(分治FFT)
設a n 為a中n的個數,b n 為b中n的個數。如果只考慮加法顯然是乙個卷積,減法翻轉一下也顯然是乙個卷積。問題在於兩者都有。容易想到分開處理。那麼可以考慮分治。即對於值域區間 l,r 分別計算a l,mid 和b mid 1,r 的貢獻及a mid 1,r 和b l,mid 的貢獻,然後再遞迴處...
bzoj 4836 二元運算
死活tle.求助 update 4.3 23 08 求助了tls之後終於過了.分治裡次數界寫崩了.r l 1就行.分治的做法很神奇!本題的限制在於操作型別與權值相對大小有關,而用 l,mid 更新 mid 1,r 正好適應了本題的要求 include include include include ...
二元運算子過載
siwuxie095 二元運算子過載 所謂 二元運算子,即 這個符號與兩個運算元進行運算 1 加號 的過載 加號 的過載方式有兩種 一種是友元函式過載,一種是成員函式過載 1 先來看成員函式過載,如下 定義乙個座標類 coordinate 在類中宣告成員函式 operator 它的引數是 const...