Rabbit Kingdom LA6461

来源:互联网 发布:手机淘宝怎么改成差评 编辑:程序博客网 时间:2024/06/06 03:46

O(n*logn)预处理出对于每个位置i,最大的left[i], right[i], 使得arr[left[i]...i...right[i]]与arr[i]互质(当然arr[i]与其本身不互质不考虑),利用链表记录一些信息,然后用树状数组维护后缀和,更新答案。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility>   #include <map>#include <string>  #include <climits> #include <set>#include <string>    #include <sstream>#include <utility>   #include <ctime>#include <bitset>#include <iomanip>//#pragma comment(linker, "/STACK:102400000,102400000")using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::stringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;using std::multimap;using std::deque;using std::unique;using std::lower_bound;using std::random_shuffle;using std::bitset;using std::upper_bound;using std::multiset;using std::ios;typedef long long LL;typedef unsigned long long ULL;typedef unsigned UN;typedef pair<ULL, ULL> PAIR;typedef multimap<int, int> MMAP;typedef long double LF;const int MAXN(200010);const int MAXM(310);const int MAXE(310);const int MAXK(6);const int HSIZE(131313);const int SIGMA_SIZE(26);const int MAXH(18);const int INFI((INT_MAX-1) >> 1);const ULL BASE(31);const LL LIM(1e13);const int INV(-10000);const int MOD(1000000007);const double EPS(1e-7);const LF PI(acos(-1.0));template<typename T> inline void checkmax(T &a, T b){if(b > a) a = b;}template<typename T> inline void checkmin(T &a, T b){if(b < a) a = b;}template<typename T> inline T ABS(const T &a){return a < 0? -a: a;}struct BIT{int arr[MAXN], size;void init(int s){size = s;memset(arr+1, 0, sizeof(arr[0])*s);}void updata(int ti, int tv){for(; ti > 0; ti -= ti&-ti) arr[ti] += tv;}int query(int ti){int ret = 0;for(; ti <= size; ti += ti&-ti) ret += arr[ti];return ret;}} bt;struct EDGE{int u, v;EDGE *next;};bool is[MAXN]; EDGE *rec[MAXN];EDGE eg1[600100], *rear1;void prepro(){memset(is, -1, sizeof(is));is[1] = false;for(LL i = 2; i <= 200000; ++i)if(is[i]){rear1->v = i;rear1->next = rec[i];rec[i] = rear1++;for(LL j = i+i; j <= 200000; j += i){rear1->v = i;rear1->next = rec[j];rec[j] = rear1++;is[j] = false;}}}int aid[MAXN], left[MAXN], right[MAXN];int arr[MAXN];EDGE *que[MAXN];EDGE eg2[MAXN], *rear2;EDGE *tab[MAXN];EDGE eg3[MAXN], *rear3;int ans[MAXN];int main(){//    freopen("d:\\in.txt","r",stdin);//    freopen("d:\\out.txt","w",stdout);rear1 = eg1;prepro();int n, m;while(scanf("%d%d", &n, &m), n+m){rear2 = eg2;rear3 = eg3;int temp = 1;for(int i = 1; i <= n; ++i) {scanf("%d", arr+i);que[i] = tab[i] = 0;checkmax(temp, arr[i]);}for(int i = 0; i <= temp; ++i) aid[i] = 0;for(int i = 1; i <= n; ++i){int mx = 0;for(EDGE *p = rec[arr[i]]; p; p = p->next){checkmax(mx, aid[p->v]);aid[p->v] = i;}left[i] = mx+1;}for(int i = 0; i <= temp; ++i) aid[i] = n+1;for(int i = n; i >= 1; --i){int mi = n+1;for(EDGE *p = rec[arr[i]]; p; p = p->next){checkmin(mi, aid[p->v]);aid[p->v] = i;}right[i] = mi-1;rear3->u = left[i];rear3->v = i;rear3->next = tab[right[i]];   tab[right[i]] = rear3++;}int ql, qr;for(int i = 0; i < m; ++i){scanf("%d%d", &ql, &qr);rear2->u = ql;rear2->v = i;rear2->next = que[qr];que[qr] = rear2++;}bt.init(n);for(int i = 1; i <= n; ++i) //更新答案时保证qr <= right[i]{if(left[i] > 1) bt.updata(left[i]-1, -1);bt.updata(i, 1);for(EDGE *p = que[i]; p; p = p->next) ans[p->v] = bt.query(p->u);for(EDGE *p = tab[i]; p; p = p->next)  //对于qr > right[k]的询问, arr[k]不会再有贡献了,所以修改回去 {if(p->u > 1) bt.updata(p->u-1, 1);bt.updata(p->v, -1);}}for(int i = 0; i < m; ++i) printf("%d\n", ans[i]);}return 0;}




原创粉丝点击