給n個數,m個詢問, 問任意區間內與其它數互質的數有多少個
比如3個數1 2 4,詢問[1,3] 那麼答案是1
千萬要記住,這樣的題目,如果你不轉變下,使勁往線段樹想(雖然轉變之後,也說要用到線段樹,但是維護的東西不同了),那麼會發現這樣的題目,區間與區間之間是無法傳遞資訊的,
區間與區間是無法傳遞資訊的,區間與區間之間是無法傳遞資訊的,重要的東西說三遍。
設n個數,存在陣列a裡面
我們預處理出,l,和r,l[i] 表示從i往左,第乙個與a[i]不互質的數的位置+1, r[i]表示從i往右,第乙個與a[i]不互質的數的位置-1
即l[i] 表示 [l[i],i]內的所有數都與a[i]互質,r[i]表示[i,r[i]]內的所有數都與a[i]互質
然後我們離線處理,將所有的詢問按照左端點排序
然後列舉左端點i,將所有l[j] = i的 [j,r[j]]區間+1,因為當左端點為i時,l[j]=i的數都在各自的有效區間[j,r[j]]裡面生效了
當i=詢問的區間的左端點時,只要查詢右端點被加了多少次就行了。
走過i時,第i個數不再生效,所以將[i,r[i]]區間-1
1 #include2 #include3 #include4 #include5 #include 6
using
namespace
std;
7const
int n = 200000 + 10
;8 vectorprime[n];
9 vectorcl[n];
10int
a[n],l[n],r[n];
11int
mark[n];
12int tree[n<<2],lazy[n<<2
];13
intans[n];
14void pushdown(int
rt)1524}
25void update(int l, int r, int rt, int l, int r, int
val)
2633
pushdown(rt);
34int mid = (l+r)>>1;35
if(l<=mid)
36 update(l,mid,rt<<1
,l,r,val);
37if(r>mid)
38 update(mid+1,r,rt<<1|1
,l,r,val);
3940}41
int query(int l, int r, int rt, int
pos)
4247
pushdown(rt);
48int mid = (l+r)>>1;49
if(pos<=mid)
50return query(l,mid,rt<<1
,pos);
51else
52return query(mid+1,r,rt<<1|1
,pos);53}
54struct
node
5561
}q[n];
6263
void
getprime()
6473}74
}75void init(int
n)76
90 l[i] = pos + 1;91
cl[l[i]].push_back(i);92}
93for(int i=2;i1;94
for(int i=0;ii)
95 mark[prime[a[n]][i]] =n;
96 r[n] =n;
97for(int i=n-1;i>=1;--i)
98105 r[i] = pos - 1
;106
}107
}108
intmain()
109121
init(n);
122for(int i=0;ii)
123127 sort(q,q+m);
128int cur = 0
;129
//列舉左端點
130for(int i=1;i<=n;++i)
131143
//要走過第i個數了,所以第i個數不再生效了,所以將[i,r[i]]區間-1
144 update(1,n,1,i,r[i],-1
);145
}146
for(int i=0;ii)
147 printf("
%d\n
",ans[i]);
148}
149return0;
150 }
hdu 4288 線段樹 離線處理
hdu 4288 題意 給你類似乙個公升序的set結構 add就是加入乙個數 del就是刪除乙個數 sum就是把所有 5 3的位置的數求和 這題我們怎麼入手呢?以前做過一道類似的樹狀陣列開55個的題 這個題其實大同小異 就是對sum陣列表示 5的值我們開個sum 5 那麼你既然是公升序的 我每次ad...
HDU 3333 線段樹 離線處理
hdu 3333 線段樹 離線處理 問你給定區間內的不重複的數字的和,如1 1 1 3 4 區間1到2就是1,區間1到5就是8。這種線段樹只能離線來寫,離線的方法是按照查詢區間的右端點來排序,然後這道題目的資料範圍較大需要離散化簡單處理一下,然後對於輸入的每個點來說,順序走下去。然後如果當前點之前出...
線段樹處理 poj2892 hdu1540
這道題想了很久 沒有想出來思路 後面上網找了題解 利用區間左端點連續 和右端點連續 處理了區間的連續 sum陣列儲存連續村莊個數,lsum儲存區間內從左起連續個數,rsum儲存區間內從右起連續個數 include include include include using namespace std...