洛谷P3674 小清新人渣的本願

題意:屢次詢問,區間內是否存在兩個數,使得它們的和爲x,差爲x,積爲x。ide

n,m,V <= 100000優化

解:spa

毒瘤bitset......code

假如咱們有詢問區間的一個桶,那麼咱們就能夠作到O(n)枚舉查找了。blog

而後咱們用bitset優化一下......外面套上莫隊來維護桶。it

具體來講,差爲x能夠寫成 a - b = xio

而後咱們把bitset左移/右移x位,與原來的and一下,看是否有元素爲1便可。event

和爲x能夠寫成 a + b = x   N - a - b = N - x   (N - a) - b = N - xclass

這啓示咱們維護一個N - x的反桶,而後把反桶右移N - x位與原桶and。cli

關於積,直接n0.5暴力便可。

  1 #include <cstdio>
  2 #include <bitset>
  3 #include <cmath>
  4 #include <algorithm>
  5 
  6 const int N = 100010;
  7 
  8 int fr[N], a[N], bin[N];
  9 std::bitset<N> bs, bs2, tp;
 10 
 11 struct ASK {
 12     int f, l, r, x, t, ans;
 13     inline bool operator <(const ASK &w) const {
 14         if(fr[l] != fr[w.l]) {
 15             return l < w.l;
 16         }
 17         return r < w.r;
 18     }
 19 }ask[N];
 20 
 21 inline bool cmp(const ASK &A, const ASK &B) {
 22     return A.t < B.t;
 23 }
 24 
 25 inline void add(int x) {
 26     if(!bin[a[x]]) {
 27         bs.set(a[x]);
 28         bs2.set(N - a[x]);
 29     }
 30     bin[a[x]]++;
 31     return;
 32 }
 33 
 34 inline void del(int x) {
 35     bin[a[x]]--;
 36     if(!bin[a[x]]) {
 37         bs.reset(a[x]);
 38         bs2.reset(N - a[x]);
 39     }
 40     return;
 41 }
 42 
 43 int main() {
 44     int n, m;
 45     scanf("%d%d", &n, &m);
 46     int T = sqrt(n);
 47     for(int i = 1; i <= n; i++) {
 48         scanf("%d", &a[i]);
 49         fr[i] = (i - 1) / T + 1;
 50     }
 51     for(int i = 1; i <= m; i++) {
 52         scanf("%d%d%d%d", &ask[i].f, &ask[i].l, &ask[i].r, &ask[i].x);
 53         ask[i].t = i;
 54     }
 55     std::sort(ask + 1, ask + m + 1);
 56 
 57     int l = 1, r = 1;
 58     bin[a[1]]++;
 59     bs.set(a[1]);
 60     bs2.set(N - a[1]);
 61     for(int i = 1; i <= m; i++) {
 62         while(l > ask[i].l) {
 63             add(--l);
 64         }
 65         while(r < ask[i].r) {
 66             add(++r);
 67         }
 68         while(l < ask[i].l) {
 69             del(l++);
 70         }
 71         while(r > ask[i].r) {
 72             del(r--);
 73         }
 74         // ------------
 75         if(ask[i].f == 1) {
 76             tp = bs & (bs >> ask[i].x);
 77             ask[i].ans = tp.any();
 78         }
 79         else if(ask[i].f == 2) {
 80             tp = bs & (bs2 >> (N - ask[i].x));
 81             ask[i].ans = tp.any();
 82         }
 83         else {
 84             bool fd = 0;
 85             for(int j = 1; j * j <= ask[i].x; j++) {
 86                 if(ask[i].x % j) {
 87                     continue;
 88                 }
 89                 if(bs[j] && bs[ask[i].x / j]) {
 90                     ask[i].ans = 1;
 91                     break;
 92                 }
 93             }
 94         }
 95     }
 96 
 97     std::sort(ask + 1, ask + m + 1, cmp);
 98     for(int i = 1; i <= m; i++) {
 99         if(ask[i].ans) {
100             puts("hana");
101         }
102         else {
103             puts("bi");
104         }
105     }
106     return 0;
107 }
AC代碼
相關文章
相關標籤/搜索