題解 luogu p3674小清新人渣的本願

2022-03-06 13:37:59 字數 1271 閱讀 9253

題目鏈結

演算法:bitset+莫隊

先把詢問都離線下來,用莫隊判斷每個詢問區間。並維護兩個bitset \(s_1,s_2\),乙個判斷 \(a_i\)是否在當前區間內。若&a_i&在bitset1中位上的值為true,那\(n-a_i\)在bitset2中那一位上也為true。

關於操作一,其實就是詢問 是否有兩個數\(a,b\)在區間內,滿足\(a+x=b\)。那麼我們只需要把\(s1\)左移x位並&上自己,看結果是否不為0就好了,因為若不為0,說明有乙個數\(a+x\)與\(a\)同時在區間內。

關於操作二,考慮把它轉換成操作一,若存在兩個數\(a_i,b_i\),使\(a_i+b_i=x\),設\(n-a_i\)為\(o\),那麼\(n-o+b_i=x\),則\(o-b_i=n-x\),這樣就轉換成了操作一,把\(s_2\)左移\(n-x\)位然後再&上\(s_1\)看結果就好了

操作三不好用bitset做,就直接暴力列舉約數暴搞就好了,說實話這個操作和這題有點格格不入。

記得弄個桶判一下每個元素個數,這個題有重複元素。

#include #include #include #include #include #include #define maxn 1000005

int n,m,a[maxn],bar[maxn],len,ans[maxn],ton[maxn];

std::bitset s1,s2,k;

struct questionop[maxn];

bool cmp(question q,question p)

void mo()

while (ll > op[i].l)

while (rr > op[i].r)

while (ll < op[i].l)

if (op[i].opt == 1)

else if (op[i].opt == 2)

else

} }}int main()

for (int i = 1;i <= m;i++)

scanf("%d%d%d%d",&op[i].opt,&op[i].l,&op[i].r,&op[i].x),op[i].whi = i;

len = sqrt(n);

for (int i = 1;i <= n;i++)

std::sort(op + 1,op + m + 1,cmp);

mo();

for (int i = 1;i <= m;i++)

return 0;

}

luogu P3674 小清新人渣的本願

題目背景 本題時限3s,空間128mb 我感覺我要掛省選 人渣的本願是乙個有趣的番 可愛的花火喜歡從小和她談 笑 風 生的歐 尼 醬鳴海,歐尼醬特別想當老師,然後劇本安排當了花火的班主任。然而有個叫做皆川茜的奇怪的人搶走了歐尼醬!花火就很失落呀,然後看到乙個叫做麥的人也很失落,原來麥喜歡茜老師。花火...

luogu3674 小清新人渣的本願

目錄本題解法 給定長度為 n 數列 a m 組查詢,問 l,r 內是否有兩個數之和 差 積為 x n,m le 10 5,max le10 5 傳送門我們先來介紹一下 bitset 如果您熟悉bitset請跳至下一章 bitset十分神奇,你可以把它看作乙個支援整體操作的bool陣列。bitset的...

Luogu3674小清新人渣的本願

給你乙個序列a,長度為n,有m次操作,每次詢問乙個區間 bitset 的原理是將一大堆值為 0 1 的數壓成乙個數。通過 i x 等操作,我們可以快速訪問 i 陣列右移 x 位後的狀態 即只剩右數 n x 個值。bitset 陣列可以當作乙個數來看待並進行 等操作 詳見高斯消元總結 還有一些 stl...